namespace::local: hiding utility functions in moo[se] roles

Ever since I came up with namespace::local, clearly inspired by namespace::clean, I was wondering who would need it in real life.

Now I seem to have found an actual application: roles. Roles must be very careful about what's in the namespace to avoid conflicts. So any private subs that are there to reduce repeating code should ideally be hidden from external observer.

And it is possible with namespace::local -below. The below switch is introduced in 0.03, and it allows the names defined below the use lines to propagate above the use line, but not past the end of scope. This can be seen as namespace::clean working in opposite direction.

Example: if you comment both use namespace::local lines, this code blows up.

#!perl

use 5.010;
use strictures;

{
    package Bar;
    use Moo::Role;

    sub bar {
        return _private(@_);
    };

    use namespace::local -below;    
    sub _private {
        return 42;
    };
};

{
    package Baz;
    use Moo::Role;

    sub baz {
        return _private(@_);
    };

    use namespace::local -below;
    sub _private {
        return 137;
    };
};

{
    package Foo;
    use Moo;

    with "Bar", "Baz";
};

my $foo = Foo->new;

say $foo->bar;
say $foo->baz;

Fave fun!

2 Comments

This can also be accomplished pretty easily using:

my $_private = sub {
   ...;
};

Leave a comment

About Konstantin Uvarin

user-pic A humble Perl developer