Skip Menu |

This queue is for tickets about the aliased CPAN distribution.

Report information
The Basics
Id: 13651
Status: resolved
Priority: 0/
Queue: aliased

People
Owner: ovid [...] cpan.org
Requestors:
Cc:
AdminCc:

Bug Information
Severity: Wishlist
Broken in: (no value)
Fixed in: (no value)



Subject: alias()
Attached is a patch to add an alias() function which cuts through a lot of the ambiguity involved in the Constant style aliasing.
diff -rN -u old-aliased-0.11/MANIFEST new-aliased-0.11/MANIFEST --- old-aliased-0.11/MANIFEST 2005-01-06 20:25:28.000000000 -0800 +++ new-aliased-0.11/MANIFEST 2005-07-11 15:05:32.000000000 -0700 @@ -7,4 +7,5 @@ t/10aliased.t t/lib/Really/Long/Module/Conflicting/Name.pm t/lib/Really/Long/Module/Name.pm +t/lib/Really/Long/Name.pm t/lib/Really/Long/PackageName.pm diff -rN -u old-aliased-0.11/lib/aliased.pm new-aliased-0.11/lib/aliased.pm --- old-aliased-0.11/lib/aliased.pm 2005-01-06 20:49:45.000000000 -0800 +++ new-aliased-0.11/lib/aliased.pm 2005-07-11 14:40:28.000000000 -0700 @@ -1,22 +1,24 @@ package aliased; $VERSION = '0.11'; +require Exporter; +@ISA = qw(Exporter); +@EXPORT = qw(alias); + use strict; sub import { my ($class, $package, $alias, @import) = @_; - require Carp && Carp::croak("You must supply a package name to aliased") - unless defined $package; - $alias ||= _get_alias($package); - { - local $SIG{'__DIE__'}; - my $callpack = caller(0); - eval "package $callpack; require $package; sub $alias () { '$package' }"; - die $@ if $@; + + if( @_ <= 1 ) { + $class->export_to_level(1); + return; } - my $import_method = $package->can('import'); - @_ = ($package, @import); - goto $import_method if $import_method; + + my $callpack = caller(0); + + _load_alias($package, $callpack, @import); + _make_alias($package, $callpack, $alias); } sub _get_alias { @@ -25,6 +27,42 @@ return $package; } + +sub _make_alias { + my($package, $callpack, $alias) = @_; + + $alias ||= _get_alias($package); + + local $SIG{__DIE__}; + eval qq{ + package $callpack; + sub $alias () { '$package' } + }; + die $@ if $@; +} + + +sub _load_alias { + my($package, $callpack, @import) = @_; + + local $SIG{'__DIE__'}; + my $code = @import == 0 ? "package $callpack; use $package;" + : "package $callpack; use $package (\@import)"; + eval $code; + die $@ if $@; +} + + +sub alias { + my($package, @import) = @_; + + my $callpack = scalar caller(0); + _load_alias($package, $callpack, @import); + + return $package; +} + + 1; __END__ @@ -34,12 +72,22 @@ =head1 SYNOPSIS + # Class name interface use aliased 'My::Company::Namespace::Customer'; my $cust = Customer->new; use aliased 'My::Company::Namespace::Preferred::Customer' => 'Preferred'; my $pref = Preferred->new; + + # Variable interface + my $Customer = alias "My::Other::Namespace::Customer"; + my $cust = $Customer->new; + + my $Preferred = alias "My::Other::Namespace::Preferred::Customer"; + my $pref = $Preferred->new; + + =head1 DESCRIPTION C<aliased> is simple in concept but is a rather handy module. It loads the @@ -137,6 +185,41 @@ a result, you may simply prefer to only use L<Explicit Aliasing> as a matter of style. +=head2 alias() + + my $alias = alias($class); + my $alias = alias($class, @imports); + +alias() is an alternative to C<use aliased ...> which uses less magic and +avoids some of the ambiguities. + +Like C<use aliased> it C<use>s the $class (pass in @imports, if given) but +instead of providing an C<Alias> constant it simply returns a scalar set to +the $class name. + + my $thing = alias("Some::Thing::With::A::Long::Name"); + + # Just like Some::Thing::With::A::Long::Name->method + $thing->method; + +The use of a scalar instead of a constant avoids any possible ambiguity +when aliasing two similar names: + + # No ambiguity despite the fact that they both end with "Name" + my $thing = alias("Some::Thing::With::A::Long::Name"); + my $other = alias("Some::Other::Thing::With::A::Long::Name"); + +and there is no magic constant exported into your namespace. + +The only caveat is loading of the $class happens at run time. If $class +exports anything you might want to ensure it is loaded at compile time with: + + my $thing; + BEGIN { $thing = alias("Some::Thing"); } + +However, since OO classes rarely export this should not be necessary. + + =head2 Why OO Only? Some people have asked why this code only support object-oriented modules (OO). diff -rN -u old-aliased-0.11/t/10aliased.t new-aliased-0.11/t/10aliased.t --- old-aliased-0.11/t/10aliased.t 2005-01-06 19:21:59.000000000 -0800 +++ new-aliased-0.11/t/10aliased.t 2005-07-11 14:43:15.000000000 -0700 @@ -2,7 +2,7 @@ use warnings; use strict; -use Test::More tests => 15; +use Test::More tests => 17; #use Test::More qw/no_plan/; BEGIN { @@ -14,9 +14,8 @@ }; eval "use aliased"; -ok $@, '... trying to use aliased without a package name should fail'; -like $@, qr/You must supply a package name to aliased/, - '... telling us how stupid we were'; +is $@, '', '... trying to use aliased without a package name should not fail'; +can_ok __PACKAGE__, 'alias'; eval "use aliased 'No::Such::Module'"; ok $@, 'Trying to use aliased with a module it cannot load should fail'; @@ -48,3 +47,15 @@ '... and it should behave as expected'; } + +# Test alias +{ + my $alias = alias("Really::Long::Name"); + is $alias->thing(2), 4, 'alias()'; + + { + package Foo::Bar; + ::alias("Really::Long::Module::Conflicting::Name", "echo"); + ::is_deeply [echo("foo")], ["foo"]; + } +} diff -rN -u old-aliased-0.11/t/lib/Really/Long/Name.pm new-aliased-0.11/t/lib/Really/Long/Name.pm --- old-aliased-0.11/t/lib/Really/Long/Name.pm 1969-12-31 16:00:00.000000000 -0800 +++ new-aliased-0.11/t/lib/Really/Long/Name.pm 2005-07-11 14:22:30.000000000 -0700 @@ -0,0 +1,5 @@ +package Really::Long::Name; + +sub thing { return $_[1] + 2 } + +1;
This patch has been applied. Thanks!