Reputation: 6007
I have a perl module .pm
file what containts my subroutines and it looks like this:
package test;
use strict;
use vars qw($VERSION @ISA @EXPORT $ERROR $NAME);
require Exporter;
@ISA = qw(Exporter);
@EXPORT = (
sub1
sub2
err1
err2
);
#...etc...
Now I have a pl
file, what need to import subroutines, but not every one, only if they are in the configured list. For example:
@subs = ('sub1', 'sub2'); # need to load sub1 & sub2, but do not load err1 & err2
or
@subs = ('sub1', 'err1'); # need to load sub1 & err1, but do not load sub2 & err2
How can I do this?
I tried to do this, but not working:
my @subs = ('sub1', 'sub2');
use test @subs;
Is there any way to load only the needed functions? And what is needed is read from SQL or config file or any other way...
Upvotes: 3
Views: 4732
Reputation: 50368
The reason your code:
my @subs = ('sub1', 'sub2');
use test @subs;
doesn't work is that use
statements are evaluated immediately during parsing, before (almost) any other code. Thus, the second line of your code actually runs before the first one, and so @subs
is still empty at that point.
This would work:
my @subs;
BEGIN { @subs = ('sub1', 'sub2'); }
use test @subs;
as would this:
BEGIN {
my @subs = ('sub1', 'sub2');
require test;
test->import(@subs);
}
In the former version, the BEGIN
block is used to make the assignment to @subs
happen already during parsing; in the second version, the entire code is put inside a BEGIN
block, and the use
statement is replaced with its run-time equivalent (require
+ import
).
However, you probably don't have any reason to do this in the first place. When you load a module, all of its code is loaded anyway,* so you don't actually save any memory by just importing some of the functions the module provides. In fact, just about the only real reason not to import everything a module provides is to avoid conflicts between modules that might be trying to export functions with the same name, or with your own function.
In any case, it's always* possible to call functions in a module without importing them at all, just by prefixing them with the module name and ::
. So, instead of:
use test qw(foo bar);
foo();
bar();
you can just do:
use test ();
test::foo();
test::bar();
*) Technically, there are few things that are guaranteed in Perl, and it's quite possible for a module to implement some kind of a lazy-loading mechanism that only creates functions (or loads them from another module) when you import them. But that requires a custom import
(and/or AUTOLOAD
) method; for ordinary modules using Exporter, the simplified description above is true.
Upvotes: 8
Reputation: 126742
First of all, all Perl globals should use capital letters, so the name of your package should begin with capital letter, and the name of the file should be altered to agree
Secondly, there is much less overhead if, instead of inheriting from Exporter
, you load its import
method directly
I don't understand what sort of thing err1
and err2
are, but should put optional exports in the array @EXPORT_OK
That leaves your module looking like this
Test.pm
package Test;
use strict;
use warnings;
use Exporter 'import';
our @EXPORT_OK = qw/ sub1 sub2 /;
sub sub1 {
print "sub1\n";
}
sub sub2 {
print "sub2\n";
}
and a program that uses it would look like this
use strict;
use warnings;
use Test qw/ sub1 /;
sub1;
output
sub1
Upvotes: -1