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

Okay, So I am currently implementing sort of a dispatch table and using eval to accomplish dynamically loading the right class/module.

Here is an example of what I am doing:

my %category = ( 'ClassOne' => ['ClassOne', 'process'], 'ClassTwo' => ['ClassTwo', 'process'], 'ClassThree' => ['ClassThree', 'process'], );
And further down in the app, I am calling this eval in a while loop:
eval 'use Category::'.$category{$$methods{'category'}}[0].';'. 'my $handle = Category::'.$category{$$methods{'category'}}[0].'-> +new();'. '$handle->'.$category{$$methods{'category'}}[1].'($key, $params, +$testCase);'; print $@ if ($@);
Now I want to remove dynamically instantiating the module from the loop and then call the handle->method() from within the loop. What would be the best way to accomplish this?

Replies are listed 'Best First'.
Re: Dynamic use/require
by Joost (Canon) on Feb 26, 2008 at 18:38 UTC
Re: Dynamic use/require
by kyle (Abbot) on Feb 26, 2008 at 18:47 UTC

    I'm not entirely clear on what you're doing or why. You point to an eval in a loop, and it sounds as if you want to take the separate parts of the eval and put them in different places.

    You say you want to remove dynamically instantiating the module from the loop. I'm guessing you're talking about the use part of what you're doing. It looks as if inside the loop is where you know what modules you want to use, so that's where you'll need to use them. If you want, you can loop twice.

    while ( ... ) { my $cat = $$methods{'category'}; my $class = 'Category::' . $category{$cat}->[0]; eval "use $class;" die $@ if $@; } while ( ... ) { my $cat = $$methods{'category'}; my $class = 'Category::' . $category{$cat}->[0]; my $method = $category{$cat}->[1]; eval "$class->new()->$method(\$key, \$params, \$testCase)"; die $@ if $@; }

    Note, though, that in the second case, you don't really need the string interpolation. You could do this instead:

    eval { $class->new()->$method( $key, $params, $testCase ) };

    Perhaps you're trying to avoid doing the use part more than once for each module. This tends not to be a problem. If the module's already loaded, use does not load it again anyway.

Re: Dynamic use/require
by CountZero (Bishop) on Feb 26, 2008 at 20:15 UTC
    I always wonder why one would need/wish to load modules dynamically. Are they particularly large and would not fit into memory at the same time?

    As they are providing the same method, their input and output must be similar, so why not adding an extra input parameter which can be used as a switch inside the one combined module to differentiate accordingly?

    And as you are calling your eval in a while loop, there is good chance that after a few runs through the while loop, you have loaded all your different modules anyhow.

    CountZero

    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

      I always wonder why one would need/wish to load modules dynamically. Are they particularly large and would not fit into memory at the same time?
      Some times it can be useful to have a plugin mechanism, where the code calling the modules does not know which modules may be available (since the plugins may be written by third parties). In those instances, you need /some/ kind of mechanism to pass (at least) a package name to the system. Having it load at the same time just makes things more stream-lined.
        A most valid comment and use of dynamically loading modules, but somehow different from what the OP is trying to implement it seems.

        Maybe something like Module::Pluggable can be coerced to do what the OP wants.

        CountZero

        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