Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change

require & import $module_name

by temporal (Pilgrim)
on Jul 19, 2012 at 19:18 UTC ( #982696=perlquestion: print w/replies, xml ) Need Help??
temporal has asked for the wisdom of the Perl Monks concerning the following question:

I want to require and import a module based on the contents of a variable. Something like this:

use Symbol 'delete_package'; foreach (@modules) { require "sub/$"; import $_ qw(foo bar); foo(); bar(); #cleanup delete_package($_); }

Initially I wanted to use the variable, but it turns out that variables are not valid arguments.

Anyway, the require works but the import claims that it is called on an 'undefined value'. I'm not really sure why this is, the variable is definitely defined. I suspect it is having issues translating the string in the variable to a package name to import from.

If I explicitly import the first module: import FirstModule qw(foo bar); it works fine for that module.

How can I get this sort of functionality working?

Replies are listed 'Best First'.
Re: require & import $module_name
by chromatic (Archbishop) on Jul 19, 2012 at 19:41 UTC

    What happens if you turn import into what's obviously a method call (if you already have an import symbol in your current package, you may have trouble) and use a named lexical?

    use Symbol 'delete_package'; foreach my $module (@modules) { require "sub/$"; $module->import(qw(foo bar)); foo(); bar(); # cleanup delete_package($module); }

    Improve your skills with Modern Perl: the free book.

Re: require & import $module_name
by CountZero (Bishop) on Jul 19, 2012 at 20:01 UTC
    Have a look at UNIVERSAL::require. It has both a use and a require method that can be used at runtime.


    A program should be light and agile, its subroutines connected like a string of pearls. The spirit and intent of the program should be retained throughout. There should be neither too little or too much, neither needless loops nor useless variables, neither lack of structure nor overwhelming rigidity." - The Tao of Programming, 4.1 - Geoffrey James

    My blog: Imperial Deltronics
Re: require & import $module_name
by tobyink (Abbot) on Jul 19, 2012 at 19:45 UTC

    eval "use $module" is pretty simple if you're 100% confident that the $module variable contains a safe package name. (You want to be sure that it doesn't contain something like "strict; system('rm -fr /home')"!)

    Module::Runtime and Class::Load provide somewhat safer techniques if you're less sure about the contents of the variable (e.g. the variable came from the outside world).

    perl -E'sub Monkey::do{say$_,for@_,do{($monkey=[caller(0)]->[3])=~s{::}{ }and$monkey}}"Monkey say"->Monkey::do'
Re: require & import $module_name
by ikegami (Pope) on Jul 20, 2012 at 05:25 UTC
    my $file = $package; $file =~ s{::}{/}g; $file .= '.pm'; require $file; $package->import(@imports);

    if already does that, so you could do

    require if; if->import(1, $package, @imports);
Re: require & import $module_name
by temporal (Pilgrim) on Jul 19, 2012 at 20:13 UTC

    You are correct chromatic, I needed to use a named lexical there. Not really sure why that is. This works:

    use Symbol 'delete_package'; foreach my $module (@modules) { require "sub/$"; import $module qw(foo bar); foo(); bar(); #cleanup delete_package($module); }

    As well as the function call format that you wrote it in.

    strict; system('rm -fr /home'), lol! tobyink, the modules are all created by myself so I'm (reasonably) sure that nothing like that will every happen. Thanks for looking out for me, though =D

    use Symbol 'delete_package'; foreach my $module (@modules) { eval "use sub::$module"; import $module qw(foo bar); foo(); bar(); #cleanup delete_package($module); }

    Works fine as well.

    CountZero, cool little module. That does the trick too:

    use Symbol 'delete_package'; require UNIVERSAL::require; foreach my $module (@modules) { "sub::$module"->require or die $@; import $module qw(foo bar); foo(); bar(); #cleanup delete_package($module); }

    Thanks guys!

    Strange things are afoot at the Circle-K.

      I needed to use a named lexical there. Not really sure why that is.

      Without seeing the other code, it's hard to say for sure, but it's possible that something else modifies $_ without localizing it appropriately.

      As well as the function call format that you wrote it in.

      Like I said, be very careful with your approach to calling import. I know what the documentation says about use, but I patched it before 5.16 so it was closer to reality. You're asking for trouble if you do it that way.

Re: require & import $module_name
by cavac (Deacon) on Jul 19, 2012 at 23:14 UTC

    Try Module::Load. Works fine for my Maplat framework.

    "I know what i'm doing! Look, what could possibly go wrong? All i have to pull this lever like so, and then press this button here like ArghhhhhaaAaAAAaaagraaaAAaa!!!"

Log In?

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://982696]
Approved by tobyink
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others browsing the Monastery: (11)
As of 2016-10-27 21:15 GMT
Find Nodes?
    Voting Booth?
    How many different varieties (color, size, etc) of socks do you have in your sock drawer?

    Results (371 votes). Check out past polls.