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

Esteemed Monks,

We have files that arrive in a directory and from the name of each file we extract a string $function . This is a function name defined in a module.

We then build a command with that $function and do an eval on it.
The reason we do this is because the files, functions, and modules holding them are defined by some other people so it's convenient for us : we just drop their modules in our lib directory and processing of new file types is automatic .

But we do this a lot of time (there are many files) and I've heard that eval is not good and not very performant.
Also this looks like the $$value problem, ie "i want to get a variable value from another variable" which, as i've seen here in the monastery, should be replaced by a hash solution .

Should we avoid the eval ?
Should we do &$function ? (no strict )
Should we do something else ?

Thanks for your advices !

Replies are listed 'Best First'.
Re: Calling a sub from a variable ?
by Thilosophy (Curate) on Mar 22, 2005 at 09:57 UTC
    If by "hash solution" you mean that you want to build a hash full of function pointers that sounds like a good plan to me.
    my %coderefs = ( foo => \&Module::function_foo, ); my $function = 'foo'; my $coderef = $coderefs{$function}; unless ($coderef){ # do something about the missing function # (for example try to load it from the module # and augment the %coderefs, this would eliminate # the need to manually set up %coderefs in advance) } my $result = $coderef->('some parameters');
      Thanks Thilosophy !

      The

      foo => \&Module::function_foo
      part was what i was missing !

      This sounds exactly like what i had in mind, i'll give it a try !

      zlr

Re: Calling a sub from a variable ?
by Taulmarill (Deacon) on Mar 22, 2005 at 09:57 UTC
    i think a hash with references to the needed funktions would be a good start.

    you should use strict most of the time, particulary if you are developing fairly large scripts, and you should avoid eval, if you can. notice that you have to trust code, that is evaled. eval will execute anny code given, even system("rm -r /*");
Re: Calling a sub from a variable ?
by Anonymous Monk on Mar 22, 2005 at 10:59 UTC
    eval string has a performance penalty, because the compiler has to do some work. However, since what you are about to eval first has to be fetched from disk, this doesn't matter - the disk I/O will dwarf the eval performance penalty.

    Now, no doubt people will here will say you should avoid using string eval because of security concerns -- you're going to run "foreign code" -- aren't getting it. Since you're going to run modules dropped in by others, you're going to run "foreign code" anyway. After all, even a "use Module;" is mostly a big string eval anyway.

    I'd say, if your current solution works for you - use it. As for your "should" questions, what you shouldn't do is ask on Perlmonks what your coding standards should be. Ask for the pro and cons of your alternatives, but don't let others decide what you should do. Remember that it's your job and responsibility - you are facing any consequences. Not the people here.

    A reply falls below the community's threshold of quality. You may see it by logging in.
Re: Calling a sub from a variable ?
by inq123 (Sexton) on Mar 22, 2005 at 10:26 UTC
    I'm not aware of a significant performance penalty on eval, although of course one'd expect a delay due to compilation. But in your case it's unlikely to be slower than &$function. Additionally it offers stability to your program by catching errors.

    Security is a concern for eval, but if you're calling the same code &$function anyway, there's no more security concern in eval than in &$function call. The latter also has to turn off strict (partially), not the best thing to do.

    So I suggest to stick to eval since AFAIK it works, it performs, and it handles errors.