Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

require $package?

by Flame (Deacon)
on Oct 17, 2001 at 04:15 UTC ( [id://119292]=perlquestion: print w/replies, xml ) Need Help??

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

I have an interesting problem. I need to be able to require a list of modules... however even though I know that the file is there, it insists it is not.
This is the sub itself:
sub loadmod(@){ shift if(ref($_[0])); $@ = 0; foreach (@_){ croak("loadmod() cannot load any packages outside of it's own pa +ckage area (RPG). Package Requested: $pack") unless($_ =~ m/^RPG::/o +); eval{ require $_ }; croak("Unable to locate $_\n\@INC includes: ".join(", ", @INC)) +if($@); } }


It is being called like this:

   loadmod qw(RPG::Item::Weapon::Spear);

Any ideas about the problem?

This is the output:
Unable to locate RPG::Item::Weapon::Spear @INC includes: E:/Perl/lib, +E:/Perl/site/lib, . at test1.pl line 5
The file requested really exists... as: RPG/Item/Weapon/Spear.pm

I'm afraid I may not be very clear, but to summerize, I want to be able to import modules using require and a sub. If I wasn't clear enough on anything, just ask.


"Wierd things happen, get used to it"

Flame ~ Lead Programmer: GMS
http://gms.uoe.org

Edit: chipmunk 2001-10-16

Replies are listed 'Best First'.
Re: require $package?
by andreychek (Parson) on Oct 17, 2001 at 04:24 UTC
    I just ran into that last night. All you need to do is put the require statement within your eval in quotes.
    eval{ "require $_" };
    Hopefully, someone will be kind enough to explain why this is necessary :-)
    <br< Have fun!
    -Eric
      It is not necessary, however if you don't do it, Perl won't go as far out of its way to be DWIM.

      That may require some explanation.

      If you read the documentation for perldoc you will find that you are supposed to require a filename. For instance:

      require "RPG/Item/Weapon/Spear.pm";
      However as a special exemption, if you pass it a package name as a bare word, it will figure out what the filename should be for you.
      require RPG::Item::Weapon::Spear; # Same as above
      To get the auto package to filename conversion, the package must be named as a bareword.

      Therefore your eval trick got the bareword in there. Or you could convert the package that you want into the filename before loading. Either works (the second is safer though if the package comes from user input). But if you pass it an actual string that is the name of a package, Perl has no way to know that that isn't the filename desired and so doesn't do the conversion.

      Does that make sense?

Re: require $package?
by lestrrat (Deacon) on Oct 17, 2001 at 04:37 UTC

    Update So apparently I was missing the fact that require also deals with filenames... /me goes rtfm'ing

    I believe thought the argument to require must be a bare word... For example,

    require "FileHandle";

    Fails. Whereas if you eval a string like so...

    my $require_filehandle = "require FileHandle"; eval $require_filehandle;

    This should work. That's because in the context of eval, require is getting a bareword "FileHandle", not a scalar value with the string "FileHandle" as its content

New Problem?
by Flame (Deacon) on Oct 17, 2001 at 06:06 UTC
    I've got a new problem now... but in the same area.

    sub loadmod(@){ shift if(ref($_[0])); $@ = 0; foreach (@_){ croak("loadmod() cannot load any packages outside of it's own pa +ckage area (RPG). Package Requested: $_") unless($_ =~ m/^RPG::/o); eval "require $_; "; croak("Unable to locate $_ \@INC includes: ".join(", ", @INC)) i +f($@); } }

    If I comment out the second croak line, nothing important happens, however if I leave it like this, I get this error:
    syntax error at E:/Perl/lib/Carp/Heavy.pm line 1, near "package Carp"
    Compilation failed in require at E:/Perl/lib/Carp.pm line 109.

    Called with: loadmod qw(RPG::Item::Weapon::Spear);

    I'm lost with that error..


    "Wierd things happen, get used to it"

    Flame ~ Lead Programmer: GMS
    http://gms.uoe.org
      It looks like you are running a messed up Perl 5.6 installation. Try the following code:
      use Carp; croak("Test croak");
      My bet is that you will get the same error. And the problem is that E:/Perl/lib/Carp/Heavy.pm probably has a syntax error in it. (Did someone edit it?) When you load Carp you don't see this error because the bulk of the module is autoloaded upon use. (This started with Perl 5.6, which is why I knew what version of Perl you had.)

      But even if you fix that, you should work on your error handling. Using eval will trap errors, but if you are using eval, you should include $@ in your error message instead of guessing at what is wrong. Alternately you can use the file naming version of require. But as your code stands if your module doesn't return a true value, you will get an error that is confusing and counterproductive because it is wrong. (require is failing on a false return, but you will think it can't be found.)

        First: I've been able to use Croak in other sections of the module...

        Hmm, this is interesting though... I just looked through the code for the Spear package... I'm missing a semicolon on the first line ("package RPG::Item::Weapon::Spear")... heh...
        Well... after adding that, everything seems fine... Thanks for the help. :)


        "Wierd things happen, get used to it"

        Flame ~ Lead Programmer: GMS
        http://gms.uoe.org
Re: require $package?
by perrin (Chancellor) on Oct 17, 2001 at 04:40 UTC
    What makes you think that not being able to find it in @INC is the error? There are lots of reasons modules can fail to load, and you don't seem to be checking the value of $@ or displaying it.
Re: require $package?
by Flame (Deacon) on Oct 17, 2001 at 04:41 UTC
    Ahh, thanks.


    "Wierd things happen, get used to it"

    Flame ~ Lead Programmer: GMS
    http://gms.uoe.org

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://119292]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others having a coffee break in the Monastery: (2)
As of 2024-04-19 19:48 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found