in reply to use/require $MODULE (a variable)

Why do you need to require() in a separate BEGIN block? the statement

use PmLoader qw{ ...args... }

is equivalent of

BEGIN { require PmLoader; PmLoader->import( qw{ ...args... } ); }

so you're already in a BEGIN block. Why not just require() everything at the end of import()?

As to using require() with variable names.. you need to do either of these:

require BAREWORD; require $filename; ## or require 'filename'

So what happens when you want to do the equivalent of

require CLASS::NAME;

but the "CLASS::NAME" portion is in a variable? well, eval(), of course, but you need to use eval STRING, not eval BLOCK:

my $module = "CLASS::NAME"; eval "require $module"; if( $@ ) { die $@; }

If you do eval{ require $module }, then require would try to load a file named "CLASS::NAME", which most likely don't exist

HTH

Replies are listed 'Best First'.
Re: use/require $MODULE (a variable)
by cadphile (Beadle) on Mar 17, 2002 at 03:11 UTC
    Thanks all for your input. I have the require working OK now, although I have two questions:

    1). The two forms of require are:

    require MODULE; require "MODULE.pm";
    The first form (according to the book) translates '::' to '/' (on Unix systems), and also treats indirect object notation as methods, whereas the second form requires the '/' path separator and treats indirect object notation as basic function calls. So I really want the first form, so I need to call this with
    eval "require $module";
    Is this right?

    2). I realize though that I need to perform some trickery with the symbol tables, I think. What I want is my module PmLoader.pm to take it's LIST input, and then find and load each of THOSE modules into the main package. As I have it now, it's loading these into the PmLoader package, but not into main. So, as was pointed out, when I say

    use Pmloader qw( ...args ...);
    it's the same as saying
    BEGIN { require PmLoader; PmLoader->import( qw( ...args...)); }
    But then in PmLoader's import method, if I only call
    eval "require $module";
    I'm missing the import. But the import needs to be done to main, not to package PmLoader. Can anyone give me a hint how to proceed here?
    From the scriptorium annex,
    -cadphile
      Just to restate what I just posted, I'm able to get through the eval "require $module"; without trouble, and @INC, and %INC are being appropriately updated.

      But!, if one of the loaded Modules uses Exporter to export its symbols into the caller package, the problem is that the caller package is not main! I.e. the Modules are not exporting their symbols into main. Hence, if I have a module that exports a subroutine symbol into main, if I

      use Module;
      directly, I can call the subroutine without a qualified package designator. But when my loader loads the Module, I can only call the subroutine with the fully qualified package name.

      Why isn't the Exporter working in this case to export the Module's symbols into main?

      thanks,
      -cadphile

      Look into Exporter's export_to_level function. Somehting like this:

      # in your PmLoader module... sub import { ## do whatever you need to do, and then eval " require $module; $module->export_to_level(2); "; ## obivously, don't forget to check for errors }

      Update: On a second thought, not all modules have a export_to_level function, so it's really better to separate out those two statements into two eval() calls...

      eval "require $module"; ## check for errors... eval "$module->export_to_level(2)"; ## this one can/may fail, so may be just warn? ## or I guess you could check by doing ## ## $module->can( 'export_to_level' ); ##
        lestrrat -- Thanks very much! The export_to_level(2) works! for modules that are inheriting Exporter.pm. We still have however, many old .pl libraries, some of which are packages, others which are just files of subroutines. Pretty much in all cases, those that are actually packages, don't require Exporter; and the .pl subroutine files certainly don't.

        Now in normal mode, the symbols for the subroutines in the subroutine libfiles would remain in main, since no package name caused Perl to change namespaces. But in my PmLoader, without an export functionality, these remain in PmLoader.

        So in both of these cases, I guess I should concoct a local export subroutine (based on the relevant code in Exporter.pm) to call, since export_to_level() can't be used. Or maybe I should play with package name switching... Again, thanks alot for your help!

        -cadphile.