Some namespaces are long and annoying. Lets say that i downloaded hypothetical package called FooFoo-BarBar-BazBaz.tar.gz, and it has the following modules:
FooFoo::BarBar::BazBaz::Bill
FooFoo::BarBar::BazBaz::Bob
FooFoo::BarBar::BazBaz::Ben
FooFoo::BarBar::BazBaz::Bozo
FooFoo::BarBar::BazBaz::Brown
FooFoo::BarBar::BazBaz::Berkly
FooFoo::BarBar::BazBaz::Berkly::First
FooFoo::BarBar::BazBaz::Berkly::Second
Is there a module or technique I can use that's similar to the C++ 'using' statement, i.e., is there a way I can do
using FooFoo::BarBar::BazBaz;
which would then let me do
my $obj = Brown->new();
ok $obj->isa('FooFoo::BarBar::BazBaz::Brown') ; # true
# or...
ok $obj->isa('Brown'); # also true
Modules might also be used to mixin methods (DBIx::Class) or be a pragma (strict.pm) which has an effect immediately upon being loaded. Modules can even be used to alter the syntax of the language. The effect of Perl modules are usually limited to the current scope in which it was loaded.
Namespace is a container of a distinct set of identifiers (variables, functions). A namespace would be like name::variable.
A Perl package is a collection of code which resides in its own namespace. Perl module is a package defined in a file having the same name as that of the package and having extension . pm. Two different modules may contain a variable or a function of the same name.
Perl interpreter is compiled with a specific @INC default value. To find out this value, run env -i perl -V command ( env -i ignores the PERL5LIB environmental variable - see #2) and in the output you will see something like this: $ env -i perl -V ... @INC: /usr/lib/perl5/site_perl/5.18.
The aliased pragma does this:
use aliased 'FooFoo::BarBar::BazBaz::Bill';
my $bill = Bill->new;
aliased
is syntactic sugar for
use constant Bill => 'FooFoo::BarBar::BazBaz::Bill';
# or
sub Bill () {'FooFoo::BarBar::BazBaz::Bill'}
The downside of this is that normal usage of package names as arguments is done with quoted strings:
$obj->isa('FooFoo::BarBar::BazBaz::Bill')
But the constant subroutine needs to be a bare word:
$obj->isa(Bill);
Which just seems like a bug waiting to happen.
Alternatively, you could just use Perl's builtin support for namespace aliasing:
package Foo::Bar::Baz::Bill;
sub new {bless {}}
package Foo::Bar::Baz::Tom;
sub new {bless {}}
package main;
BEGIN {*FBB:: = *Foo::Bar::Baz::} # the magic happens here
say FBB::Bill->new; # Foo::Bar::Baz::Bill=HASH(0x80fd10)
say FBB::Tom->new; # Foo::Bar::Baz::Tom=HASH(0xfd1080)
Regarding the ->isa('shortname')
requirement, the aliased stash method works with quoted strings as usual:
my $obj = FBB::Bill->new;
say $obj->isa('FBB::Bill'); # prints 1
say $obj->isa('Foo::Bar::Baz::Bill'); # prints 1
The effect of a compile time alias BEGIN {*short:: = *long::package::name::}
is global across all packages and scopes. This is fine as long as you pick an empty package to alias into.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With