Package perl-Import-Into: Information
Source package: perl-Import-Into
Version: 1.002005-alt1
Build time: Oct 12, 2015, 05:42 AM in the task #151127
Category: Development/Perl
Report package bugLicense: Artistic
Summary: import packages into other packages
Description:
Writing exporters is a pain. Some use the Exporter manpage, some use the Sub::Exporter manpage, some use the Moose::Exporter manpage, some use the Exporter::Declare manpage ... and some things are pragmas. If you want to re-export other things, you have to know which is which. the Exporter manpage subclasses provide export_to_level, but if they overrode their import method all bets are off. the Sub::Exporter manpage provides an into parameter but figuring out something used it isn't trivial. Pragmas need to have their `import' method called directly since they affect the current unit of compilation. It's ... annoying. However, there is an approach that actually works for all of these types. eval "package $target; use $thing;" will work for anything checking caller, which is everything except pragmas. But it doesn't work for pragmas - pragmas need: $thing->import; because they're designed to affect the code currently being compiled - so within an eval, that's the scope of the eval itself, not the module that just `use'd you - so sub import { eval "use strict;" } doesn't do what you wanted, but sub import { strict->import; } will apply the strict manpage to the calling file correctly. Of course, now you have two new problems - first, that you still need to know if something's a pragma, and second that you can't use either of these approaches alone on something like the Moose manpage or the Moo manpage that's both an exporter and a pragma. So, the complete solution is: my $sub = eval "package $target; sub { shift->import(\@_) }"; $sub->($thing, @import_args); which means that import is called from the right place for pragmas to take effect, and from the right package for caller checking to work - and so behaves correctly for all types of exporter, for pragmas, and for hybrids. Remembering all this, however, is excessively irritating. So I wrote a module so I didn't have to anymore. Loading the Import::Into manpage creates a global method `import::into' which you can call on any package to import it into another package. So now you can simply write: use Import::Into; $thing->import::into($target, @import_args); This works because of how perl resolves method calls - a call to a simple method name is resolved against the package of the class or object, so $thing->method_name(@args); is roughly equivalent to: my $code_ref = $thing->can('method_name'); $code_ref->($thing, @args); while if a `::' is found, the lookup is made relative to the package name (i.e. everything before the last `::') so $thing->Package::Name::method_name(@args); is roughly equivalent to: my $code_ref = Package::Name->can('method_name'); $code_ref->($thing, @args); So since the Import::Into manpage defines a method `into' in package `import' the syntax reliably calls that. For more craziness of this order, have a look at the article I wrote at http://shadow.cat/blog/matt-s-trout/madness-with-methods which covers coderef abuse and the `${\...}' syntax. Final note: You do still need to ensure that you already loaded `$thing' - if you're receiving this from a parameter, I recommend using the Module::Runtime manpage: use Import::Into; use Module::Runtime qw(use_module); use_module($thing)->import::into($target, @import_args); And that's it.
Maintainer: Igor Vlasenko
Last changed
Oct. 11, 2015 Igor Vlasenko 1.002005-alt1
- automated CPAN update
July 25, 2014 Igor Vlasenko 1.002004-alt1
- automated CPAN update
May 13, 2014 Igor Vlasenko 1.002002-alt1
- automated CPAN update