in reply to Loading all files in a dir with use via for loop

From the Perldoc for the function use:

Imports some semantics into the current package from the named module, generally by aliasing certain subroutine or variable names into your package. It is exactly equivalent to
BEGIN { require Module; import Module LIST; }
except that Module must be a bareword.
((emphasis mine))

So you see, the 'use' takes only a bareword: you can't use a variable.

The second doesn't actually execute anything, so the modules named in $plugin are never loaded.

What you want is to eval the use statements:

for $plugin (<Main/*.pm>) { $plugin =~ s!/!::!g; $plugin =~ s/\.pm$//; $plugin = "use $plugin\;"; ## $plugin; eval $plugin; }

As written, that may be risky -- read the documentation on eval (linked above) and understand the risk before implementing.

<-radiant.matrix->
Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
The Code that can be seen is not the true Code
"In any sufficiently large group of people, most are idiots" - Kaa's Law

Replies are listed 'Best First'.
Re^2: Loading all files in a dir with use via for loop
by Delusional (Beadle) on Sep 29, 2005 at 07:35 UTC
    Thanks allot radiant.matrix, exactly what I was looking for! I was using eval differently (and obviously wrong for this situation ( eval { $plugin; }; and eval { "$plugin;" };)), which should explain why it was failing(?)....

    Now that I can actually run something, things can, again, move along.

    I have one final question (which is brought up due to the code loading the files needed (dynamically)). When using a variable to call a function, is there anyway to varify that function exists before calling it (since the function would have been 'loaded' at the time its called)?

    For example:
    ....load pm files here.... $PAGE = "test_function_a"; eval { &$PAGE; }; $@ and die( &nopageerror() ); $PAGE = "test_function_b"; eval { &$PAGE; }; $@ and die( &nopageerror() ); exit; sub test_function_a { print "in test_function_a"; } sub nopageerror { print "The function $PAGE is unknown"; }

    This is just an example, and not accurate. In fact, nopageerror doesn't even execute, rather the script just terminates, no error when ran in the browser, however, I can produce an additional log (out side of Apache), that then states "Undefined subroutine &main::test_function_b". Again, the above is just an example to explain, with as little overhead/code as possible to better show the area I'm stuck in. Yes the sub function test_function_b is not present here, to intentionally cause an error situation.

      Your question is a little confusing, but I will do my best. It seems like you are trying to see if certain functions have been exported into your main script.

      First step, read up on packages. Your script should have the package name 'main' (you might even want to get in the habit of specifying package main;). Once you realize this, you can use the standard method for checking to see if a package has a particular method/subroutine available.

      All packages are descendants of UNIVERSAL, so you can use its can method, which looks like this:

      PackageName->can('sub_name');

      So, if you're in the main package:

      $PAGE = "test_function_a"; eval "$PAGE" if main->can($PAGE);

      However, this is probably not what you want to do. Executing function names stored in variables can be rather dangerous, and you should understand the risks before doing so. I don't know what problem you're trying to solve, but perhaps a solution like a rudimetary dispatch table is better suited:

      my %dispatch = ( 'test_function_a' => \&test_function_a, 'test_function_b' => \&test_function_b, ); foreach my $func ( qw'test_function_a test_function_b' ) { die "Package main doesn't seem able to '$func'" unless main->can($f +unc); $dispatch{$func}->(); }

      This avoids some of the issues with eval, and might even be faster.

      <-radiant.matrix->
      Larry Wall is Yoda: there is no try{} (ok, except in Perl6; way to ruin a joke, Larry! ;P)
      The Code that can be seen is not the true Code
      "In any sufficiently large group of people, most are idiots" - Kaa's Law
        Thanks radiant.matrix,
        Thats working with the exception of the error message (forgot the package command in one of the files thus it caused problems (all files are part of main as they were orginally in the main file and only stripped out and put into smaller ones to make reading and editing easier))....
        . Specifically, I'd like the eval (prefer eval over the dispatch in this situation), to call nopageerror (which is in the main package). I've tried adding else commands to the if, however, as my luck this week has been, its kicking out with an error (probibily because it not valid, didn't find a ref to useing if-then-else in eval's, but thought I'd try anyway). The reason for calling nopageerror, is to display a useful information in the browser as well as generate special logs that arn't quite as cryptic as the Perl error messages and Apache logs...

        What would I have to do to be able to eval the var, if the var is a function, execute it, if not, call the sub routine to issue the error message about the missing function. This is probibily so simple that I'm over looking it...