Reputation: 2410
I've written a special import function that will be used in a few places and I'd like to be able to just go "use ImportRenamer;" in those modules and have them use the import gained from ImportRenamer henceforth. How would i go about that?
Edit: In other words: How do i import 'import' without running it?
Upvotes: 4
Views: 476
Reputation: 13053
As an alternative, you can avoid mucking around in the symbol table by using Sub::Exporter
package Your::Module;
use Sub::Exporter (
-setup => {
exports => {
import => sub { return \&_real_import }
},
# the "default" group auto-exports "import" without the caller
# specifically asking for it
groups => { default => [qw(import)] },
}
);
sub _real_import { ... }
EDIT: added the "default" group for auto-exporting
Upvotes: 3
Reputation: 129539
UPDATE
Now that OP clarified his needs, this should indeed be done in a way similar to what Exported does, to be precise, by injecting the sub reference into a caller's namespace via a glob assignment. Example:
###############################################
package ImportRenamer;
use strict;
sub import_me {
print "I am a cool importer\n";
}
sub import {
my ($callpkg)=caller(0);
print "Setting ${callpkg}::import to ImportRenamer::import_me\n";
no strict "refs";
*{$callpkg."::import"} = \&ImportRenamer::import_me; # Work happens here!!!
use strict "refs";
}
1;
###############################################
package My;
use strict;
use ImportRenamer;
1;
###############################################
package My2;
use strict;
use ImportRenamer;
1;
###############################################
And the test:
> perl -e '{ package main; use My; use My2; 1;}'
Setting My::import to ImportRenamer::import_me
I am a cool importer
Setting My2::import to ImportRenamer::import_me
I am a cool importer
ORIGINAL ANSWER
You don't need to do anything special beyond calling the import method "import
". use
already calls import()
, see perldoc use:
use Module LIST
Imports some semantics into the current package from the named module, generally by aliasing certain subroutine or variable names into your package.
It is exactly equivalent to:
BEGIN { require Module; Module->import( LIST ); }
Upvotes: 3
Reputation: 27234
You need to write a custom import
method in your module that will export your function you want to be called import in the calling namespace.
Here's some untested code:
package ImportMe;
sub import {
# Get package name
my $caller = caller;
# Install my_import into the calling package as import
{ no strict 'refs';
*{"${caller}::import"} = \&my_import;
}
return 1;
}
# renamed as import when installing
sub my_import {
# do stuff
}
Now you can put use ImportMe;
in all your modules and an import
method will be installed.
Upvotes: 3
Reputation: 67048
How about something like this:
package Your::Module;
use strict;
use warnings;
sub import {
# gets called by use Your::Module
my ( $pkg ) = caller;
no strict 'refs';
*{ $pkg . '::import' } = \&_real_import;
}
sub _real_import {
# import function to be exported to caller
print "blah blah";
}
This manually assigns the _real_import
sub to the import
slot of the calling package's namespace. If you do this in a BEGIN
block, then the import
sub should be ready and waiting when that package gets use
d.
Upvotes: 2