Slash Boxes
NOTE: use Perl; is on undef hiatus. You can read content, but you can't post it. More info will be forthcoming forthcomingly.

All the Perl that's Practical to Extract and Report

The Fine Print: The following comments are owned by whoever posted them. We are not responsible for them in any way.
More | Login | Reply
Loading... please wait.
  • eval-block isn't the same thing as eval-string and you probably shouldn't think of them as related. The former is used when you're creating new source code on the fly and want to run it. The latter is when you want to trap die().

    It's the same word but they aren't related. They share the variable $@/$EVAL_ERROR and both trap die() but that's incidental.

    Replacements for string-eval are often dispatch tables, curried functions, closures, that kind of thing. The following is an example of something that can be written using some closures or by using string-eval. The BEGIN is just there to emphasise that this is a kind of static generation. You're free to come up with your own variations on this theme.

    BEGIN {
        for my $name ( ... ) {
            no strict 'refs';
            *$name = sub {


    BEGIN {
        for my $name ( ... ) {
            eval <<"CODE";
                sub $name {
    • I do realize that :) Below is what I DO have.. I guess this is just one of those "perl can't parse perl properly" moments.
      eval qq{
      use Foo::$module;
      \$value = Foo::${module}::bar(\$baz); };
      • Do you have a die $@ if $@; after that statement?
      • Ok, so just do "no strict 'refs'" for the parts that make sense to use it for. That's oodles nicer than string-eval for everything. I keep thinking there's a better use of Module::Pluggable or similar here but that usually implies ISA and class stuff which isn't what you coded.

        # Validate that $module is safe...
        no strict 'refs'; ## no critic (ProhibitNoStrict)
        if ( not keys %{"Foo::${module}::"} ) {
        # or
        if ( not $INC{"Foo/$"} ) {
            ## no critic (ProhibitStringyEval)

        • there is even a simpler and safer (strict clean) way to do this. call the sub as a class method and you build the class name as a string. the sub should ignore its first arg which is the class.

          $value = "Foo::${module}::bar"->( $baz );

          and using eval to execute a dynamic require is a good idea. require with a class arg will do the right thing on different platforms. if you pass require a value, it will find that filename which isn't always portable. this is one of the few places i do eval on the fly becaus
          • So how do you catch errors without eval? Suppose bar in
            $value = "Foo::${module}::bar"->( $baz );
            fails or that Foo::${module}just does not exist?
            • easy, just wrap that in a block eval. as was said earlier, eval BLOCK is very different than eval STRING.

              also you could look in the symbol table for this entry and if it has a code ref. you can just check if the sub is defined too.

              defined( &{"Foo::${module}::bar"} ) or die "blah" ;

              that will need strict refs turned off for that line.

              string eval is never needed just to do symbol table stuff. it is the one proper use of symrefs as they are meant to mung the symbol table.