Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

I seek your wisdom with the following problem;

I would like to load a module that is stored into an array and not a file. Here is what I have right now (non-functional):
use strict; open (MFILE, "testmod.pm") || die (...); my @mod = <MFILE>; close MFILE; if (eval "require @mod") { print "module loaded\n"; } else { print "module failed to load: $!\n"; } ...
I know in the above example I could simply load the module by using a require "testmod.pm"; however my real application requires loading from an array.

Thanks in advance, and of course any help is greatly appreciated.

zi99er

Replies are listed 'Best First'.
Re: Loading a Module from a Variable
by blazar (Canon) on Sep 21, 2005 at 13:50 UTC
    If I understand correctly what you want, then you may exploit the possibility of putting code into @INC (see perldoc -f require):
    #!/usr/bin/perl use strict; use warnings; use lib sub { my $file=pop; return undef unless $file eq 'Foo/Bar.pm'; open my $fh, '<', \<<".EOM" or die $!; package Foo::Bar; use strict; use warnings; sub new { "Hello World!\n", "this is ", __PACKAGE__, "\n"; } 1; .EOM $fh; }; use Foo::Bar; print Foo::Bar->new; __END__
Re: Loading a Module from a Variable
by davidrw (Prior) on Sep 21, 2005 at 13:22 UTC
    can you explain why your app requires loading from an array?

    But i think what you're looking for is to eval the string, but note that this doesn't have the double-loading protection that require provides ...
    if( eval join("", @mod) ){ print "module loaded\n"; } else { print "module failed to load: $@\n"; }
    (note the change from $! to $@ -- see perlvar)
      Thanks for the quick reply,

      My perl application takes as input a module and dynamically loads it, then calls the necessary functions. I could easily take the input argument (array) and write it to a temporary file, and require it, however I am using Perl...so there must be a way...

      I had tried your suggestion, however I ran into some problems since my module is defines something like:
      package testmod; use DynaLoader; use Exporter; BEGIN { @ISA = qw(Exporter, DynaLoader); @EXPORT = qw(testfunc); @EXPORT_OK = qw(); } use strict; sub testfunc { ... } 1;
      The errors I am getting are "Global symbol @ISA requires explicit package name..."

      PS: Thanks for the heads up on $@, I always get those confused.

      zi99er
        eval, unlike require does not evaluate the code in a new top-level lexical scope. Any lexically scoped varaibles or pragmas will be inherited by the code.

        One way to avoid use strict and use warnings being inherited by your evaled source is to simply no strict; no warnings; before you eval.

        To avoid lexical variables, put the eval() in a subroutine that appears before any file scoped lexicals (and before the pragmas too).

        # Start of program sub myeval { eval shift } use strict; use warnings; # ...rest of program

        A completely different approach would be to put a code reference into @INC. That way you can actually use require.

Re: Loading a Module from a Variable
by Roy Johnson (Monsignor) on Sep 21, 2005 at 16:47 UTC
    Any chance you could write the array to a file and then require the file?
    my $temp_mod_name = 'tempmod.pm'; open TEMP, '>', $temp_mod_name or die "$temp_mod_name: $!\n"; print TEMP @mod; close TEMP; if (eval "require $temp_mod_name") { ....

    Caution: Contents may have been coded under pressure.
Re: Loading a Module from a Variable
by ruoso (Curate) on Sep 21, 2005 at 20:27 UTC

    I would strongly suggest you the use of Safe or Safe::World... as I don't understand exactly what are you trying to do and even where's the source of the dinamically feeded code.

    daniel