Search code examples
perlperl-module

Perl `use qw` or import subroutines from pm files


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...


Solution

  • 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.