# -*- perl -*- # # Package::Alias - Alias one namespace into another # # $Id: Alias.pm,v 2.1 2009/12/01 16:01:28 jpierce Exp $ package Package::Alias; use strict qw/vars subs/; use vars qw/$VERSION $DEBUG $BRAVE/; use Carp; $VERSION = 0.11_1; $DEBUG = 0; #------------------------------------------------------------ # Class Methods #------------------------------------------------------------ sub alias { my $class_or_self = shift; my %args = @_; while ( my ( $alias, $orig ) = each %args ) { if ( scalar keys %{$alias . "::" } && ! $BRAVE ) { carp "Cowardly refusing to alias over '$alias' because it's already in use"; next; } *{$alias . "::"} = \*{$orig . "::"}; print STDERR __PACKAGE__ . ": aliasing '$alias' => '$orig'\n" if $DEBUG; } } sub import { my $class_or_self = shift; my %args = @_; while ( my ( $alias, $orig ) = each %args ) { my($alias_pm, $orig_pm) = ($alias, $orig); foreach( $alias_pm, $orig_pm ){ s/::/\//g; $_ .= '.pm'; } next if exists($INC{$alias_pm}); my $caller = caller; eval "{package $caller; use $orig;}"; confess $@ if $@; $INC{$alias_pm} = $INC{$orig_pm}; } alias($class_or_self, @_); } 1; __END__ #------------------------------------------------------------ # Docs #------------------------------------------------------------ =head1 NAME Package::Alias - alias one namespace into another =head1 SYNOPSIS use Package::Alias Foo => 'main', 'P::Q' => 'Really::Long::Package::Name', Alias => 'Existing::Namespace'; BEGIN{ use Package::Alias Moose => Mouse; #Make Mouse's finicky internal checks happy... Moose::Exporter->setup_import_methods(exporting_package=>'Moose', #Alas the defaults live in Mouse... as_is => [qw( extends with has before after around override super augment inner ), \&Scalar::Util::blessed, \&Carp::confess, ], ); =head1 DESCRIPTION This module aliases one package name to another. After running the SYNOPSIS code, C<@INC> (shorthand for C<@main::INC>) and C<@Foo::INC> reference the same memory, likewise for the other pairings. To facilitate some crafty slight of hand, the above will also C if it's not already loaded, and tell Perl that C is loaded. In some rare cases such as C, additional trickery may be required... =head1 GLOBALS Package::Alias won't, by default, alias over a namespace if it's already in use. That's not considered a fatal error - you'll just get a warning and flow will continue. You can change that cowardly behaviour this way: # Make Bar like Foo, even if Bar is already in use. BEGIN { $Package::Alias::BRAVE = 1 } use Package::Alias Bar => 'Foo'; =head1 CAVEATS To be strict-compliant, you'll need to quote any packages on the left-hand side of a => if the namespace has colons. Packages on the right-hand side all have to be quoted. This is documented as L. =head1 NOTES Chip Salzenberg says that it's not technically feasible to perform runtime namespace aliasing. At compile time, Perl grabs pointers to functions and global vars. Those pointers aren't updated if we alias the namespace at runtime. =head1 AUTHOR Joshua Keroes Jerrad Pierce =head1 SEE ALSO L =cut