Know the two different forms of eval

Perl’s eval leads a double life, and, like Dr. Jekyl and Mr. Hyde, one is dangerous and one is almost safe. And, it’s important to know which one is dangerous; I grew up thinking that Dr. Jekyl was the bad one because evil people, such as Dr. No, had titles.

You can recognize the evals by their first, and only, argument. One form takes a string and the other takes a block. The string version compiles a string as Perl code and executes its, all at runtime. The block form runs, at run time, code that perl has already compiled.

The string form

This is the dangerous one.

The string form of eval lets you build up Perl code in a scalar and compile it when you are ready. There are some things that want to happen at compile time, but that you’d like to do later, such as use-ing or require-ing a module dynamically. Neither of those take a variable as an argument, so you normally have to know ahead of time the name of the module you want to load:

my $module = ...;
use $module; # compile error

Instead, you build the code in a string, which puts all the right characters in the right place, then runs it. This one allows you to load a module that you decide programmatically:

my $module = ...;
eval "use $module"

You probably still want to catch errors in loading modules, though, so you want to check the return value of the eval, which will be the last value it evaluates. In this case, it’s the last top-level expression in the module file, which is typically 1;:

my $module = ...;
unless( eval "use $module" ) {
	die ...;
	}

These presents a problem for the string eval. How do you ensure that you run only safe code? How did you figure out what should be in $module? What it if is system( 'rm -rf /' )? Properly scrubbing data is a long topic though (although you can check perlsec or the “Security” chapter in Mastering Perl).

Other people use eval because they haven’t developed the skills to do their tasks with Perl’s more advanced features, such as anonymous subroutines, that can let you do things without building up code in a string. Often, a string eval is an indication of insufficient Perl skill (although not always). If you can find any other way to get the job done, avoid the eval.

The block form

This is the safe one.

The block form of eval has a much different job. perl, however, compiles, the code within that block during the compile phase. If perl encounters a fatal error in an eval, it catches the error, puts the error in $@, and lets you handle it:

use autodie;

eval {
	open my $fh, '>', $filename;
	die if time % 2;
	...;
	}
if( $@ ) { ... }

This is the basis of Perl’s “fake” exceptions, which we might show in a future Item since that another complicated issue. In short, there are modules, such as Try::Tiny, that handle all of the details.

This eval won’t catch all errors though. It can’t help it if the entire perl freaks out (or panics), if the user interrupts the program, the computer loses powers, and anything else beyond perl‘s control. It also doesn’t catch warnings unless you’ve done something to make them fatal.

Things to remember

  • eval with a string argument compiles and runs code at run time.
  • The string form can unintentionally run malicious code.
  • Avoid the string form if you can.
  • eval with a block argument runs code at

Post to Twitter Post to Delicious Post to Digg Post to Facebook Post to Reddit

Leave a comment

2 Comments.

    • Class::Load might work for some people. It gets around the issue by converting namespaces to filenames. You can supply a string (instead of a bareword) filename to require. Curiously, you can always supply a unix-style filename no matter what your system is. With use, it’s always a namespace.

Leave a Reply

You must be logged in to post a comment.