Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is there a Perl module or technique that makes using long namespaces easier?

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
like image 880
Robert P Avatar asked Feb 17 '11 22:02

Robert P


People also ask

What is the use of Perl modules?

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.

What is Perl namespace?

Namespace is a container of a distinct set of identifiers (variables, functions). A namespace would be like name::variable.

What is the difference between package and module in Perl?

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.

Where is @INC in Perl?

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.


1 Answers

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.

like image 90
Eric Strom Avatar answered Oct 07 '22 01:10

Eric Strom