eval#
Run a piece of Perl code with any fatal error trapped instead of killing the program.
eval is Perl’s exception-catching mechanism and its runtime
code-loader in one. It comes in two real forms: block eval
(eval { ... }), which catches exceptions thrown by already-compiled
code, and string eval (eval EXPR), which compiles and runs a
string of Perl source at runtime. Either way, a die that would
otherwise terminate the program becomes an assignment to $@ and a
normal return.
Synopsis#
eval BLOCK # catch exceptions in compiled code
eval EXPR # compile and run source at runtime
eval # short for: eval $_
What you get back#
The value of the last expression evaluated inside the mini-program,
or the value handed to an explicit return. The evaluation happens
in the same context as the surrounding eval — void, scalar, or
list — so wantarray inside an eval reports the caller’s context,
not “some eval context.”
If anything inside raises an exception (die, a division by zero, a
string-eval syntax error, any other trappable fatal), eval returns
undef in scalar context and the empty list in list context, and
the exception lands in $@:
my $n = eval { risky() }; # undef on failure, $@ holds the error
if ($@) { ... }
On success, $@ is set to the empty string. Every completed eval
touches $@ — there is no “leave it alone” option. A control-flow
operator that bypasses the normal exit (last, goto out of the
block) can leave $@ unchanged, which is a corner case rather than a
feature to rely on.
Global state it touches#
$@— written on every normal exit of theeval: the thrown exception on failure, the empty string on success. Read to determine whether theevalcaught something.$^S— reflects whether Perl is currently inside aneval(ortry).undefduring parsing, true while executing inside aneval/tryblock, false at the top level. Read primarily by$SIG{__DIE__}handlers that want to act differently for caught vs. uncaught exceptions.$SIG{__DIE__}— fires on everydie, including those that an enclosingevalis about to catch. Uselocal $SIG{__DIE__}inside anevalto suppress a globally installed hook for the duration of the trap.$SIG{__WARN__}— unaffected byeval. Warnings emitted inside the block still go through the normal warning path;evaldoes not redirect them into$@.$_— the source of the no-argument form (evalwith nothing after it is exactlyeval $_).
Block eval vs. string eval#
The two forms look similar but do very different things.
Block eval (
eval { ... }) is parsed and compiled together with the surrounding program. At runtime it is just a marker that says “catch anydiethrown from inside this block.” Because the code is already compiled, block eval is cheap and safe — the compiler already checked it for syntax errors. This is the form to reach for whenever the goal is exception handling.String eval (
eval EXPR) evaluatesEXPRin scalar context, then parses and executes the resulting string as if it were a block in the lexical scope of the surrounding code. The parse happens every time theevalis reached. A syntax error in the string becomes a runtime$@, not a compile-time failure of the enclosing program. This is the form for loading code decided at runtime — optional features, user-supplied expressions, dynamically constructed subs — and it carries the costs and hazards that implies.
Both forms run in the lexical scope of the surrounding code: outer
my variables are visible, and package variable assignments,
subroutine definitions, and format definitions made inside the
eval persist after it returns.
The $@ contract#
After an eval completes normally, $@ is always one of:
The empty string — the block ran to completion with no exception.
A string ending in a newline — a
die "message\n"or a string exception the callee already terminated.A string with appended location (
... at FILE line N.\n) — adie "message"without a trailing newline, or a runtime error Perl itself raised.A reference, typically a blessed exception object —
diecalled with a reference.
Check $@ immediately after the eval and nowhere else. Any method
call, ref test, isa check, or regex match done during handling
can itself invoke an eval internally (for instance, during
autoloading or overload resolution) and overwrite $@ before you
finish inspecting it. Copy into a lexical first:
eval { work() };
if (my $err = $@) { # safe snapshot
if (ref $err && $err->isa('MyApp::Error')) { handle($err) }
else { die $err }
}
Nested eval and local $@#
The outer eval sees whatever $@ holds when the outer block
finishes — not what it held partway through. If inner code has its
own eval, that inner eval sets $@ (to the empty string on
success), which can clobber an error the outer code wanted to
preserve. The guard is local $@ around the inner work:
eval {
# ... some work that might fail ...
{
local $@; # shield outer $@
eval { optional_step() };
# ignore whatever optional_step did to $@
}
die "still needed\n" if $condition;
};
warn "outer caught: $@" if $@;
Before Perl 5.14, $@ was assigned before localized variables were
restored, so code that wanted to filter errors had to stage the
value through a temporary. On 5.14+ (which 5.42 inherits) the order
is fixed and the temporary is unnecessary.
String eval security#
String eval runs whatever is in the expression. If any part of that
string came from untrusted input — a file, a network peer, a user
form — the eval hands the attacker the full Perl interpreter.
Rules of thumb:
Never pass user input through
eval EXPRunmodified. “It’s only a number” is not a safeguard —"1; system 'rm -rf /'"is also only a string.If runtime-chosen code is genuinely needed, constrain the input against a strict allow-list before interpolation, and prefer data-driven dispatch (a hash of coderefs) over generating source.
Floating-point values interpolated into source are fragile. Under
use localethe decimal separator may not be a dot, and values like"NaN"or"Infinity"stringify to letters that the parser reads as barewords, not numbers.Source filters activated inside a string
evalleak out into the surrounding file scope (unlessevalbytesis used). This is a long-standing quirk, not a feature.
Block eval has none of these problems — the code was compiled with the rest of the program.
BEGIN inside string eval#
BEGIN { ... } blocks embedded in a string eval execute
immediately, before the rest of the eval’d code runs, matching
their behaviour in a normal compilation unit. Set
${^MAX_NESTED_EVAL_BEGIN_BLOCKS} to 0 to make any embedded
BEGIN throw instead:
local ${^MAX_NESTED_EVAL_BEGIN_BLOCKS} = 0;
eval $untrusted; # any BEGIN inside $untrusted dies
This does not make a string eval safe — it only removes one specific attack on compile-time side effects.
try/catch#
Under use feature 'try' (stable since 5.40, available in 5.42),
the try/catch/finally construct provides dedicated
exception-handling syntax:
use feature 'try';
try {
risky();
}
catch ($e) {
warn "caught: $e";
}
finally {
cleanup();
}
Differences from eval { ... }; if ($@) { ... }:
The caught value is bound to a fresh lexical
$e(or whatever name is given), not to$@. No need for themy $err = $@snapshot dance.$@is not set as a side effect — thetryblock has no global after-effect on it.tryis not itself a loop, but control-flow operators behave analogously toeval BLOCK:returninsidetryreturns from the enclosing sub, andnext/last/redotarget an outer loop.finallyruns on every exit path and cannot itself usereturn/next/last/redo. It is marked experimental in 5.42 and emits a warning underexperimental::try.
Reach for try/catch in new code. The eval-plus-$@ idiom
remains correct and is still the right tool whenever the surrounding
code must run on older Perls or must not require the feature guard.
Examples#
Trap a runtime error and keep going:
my $q = eval { $x / $y };
if ($@) { warn "division failed: $@"; $q = 0 }
Detect whether a feature is available without aborting at startup:
my $have_socket = eval { socket(my $s, PF_INET, SOCK_STREAM, 0); 1 };
die "no sockets on this build" unless $have_socket;
Load a module whose absence should be tolerated:
my $json = eval { require JSON::XS; JSON::XS->new } //
do { require JSON::PP; JSON::PP->new };
Catch a blessed exception, re-throw anything else:
eval {
parse($input);
};
if (my $err = $@) {
if (ref($err) && $err->isa('MyApp::ParseError')) {
report($err);
}
else {
die $err;
}
}
Nested eval with local $@ so an inner optional step does not
erase an outer diagnostic:
eval {
do_main_work();
{ local $@; eval { maybe_cleanup() } } # ignore cleanup errors
die "main still failed\n" if $something_else_wrong;
};
warn $@ if $@;
Suppress a globally installed $SIG{__DIE__} hook for the duration
of a private trap:
eval {
local $SIG{__DIE__}; # don't trigger hooks while we probe
$answer = $x / $y;
};
warn $@ if $@;
A $SIG{__DIE__} hook that logs only uncaught exceptions, using
$^S to tell the two cases apart:
$SIG{__DIE__} = sub {
return if $^S; # inside eval/try — let it propagate
log_fatal(@_); # top level — record before exit
};
Runtime-built dispatch (string eval used deliberately, input is not user-supplied):
for my $op (qw(add sub mul div)) {
eval "sub ${op}_of { \$_[0] "
. { add=>'+', sub=>'-', mul=>'*', div=>'/' }->{$op}
. " \$_[1] }";
die $@ if $@;
}
Edge cases#
No argument —
eval;iseval $_. Rarely what you want; writeeval { ... }oreval EXPRexplicitly.Final semicolon — may be omitted from the end of
EXPRorBLOCK.eval "1+2"andeval "1+2;"are equivalent.eval BLOCKis not a loop —next,last, andredocannot leave or restart the block. They look for an enclosing loop and will croak if there is none.returninsideeval BLOCKreturns from the enclosing subroutine, not from theeval— theevalblock is not a function body. To produce a value from the block, put the value as the final expression.Warnings are not trapped.
warninside anevalstill writes toSTDERR. Route them into$@only if you set$SIG{__WARN__}to do so yourself.Control flow out of
eval— agoto,last, ornextthat jumps out of the block skips the normalevalexit and therefore may leave$@untouched. Do not build logic that depends on this.Quotes on
EXPR—eval $xvs.eval "$x"behave identically: both run the code contained in$x. The double quotes add visual noise, not semantics.eval '$x'vs.eval { $x }— both return the value of$x. The block form is compiled with the surrounding program; prefer it unless the code genuinely needs to be constructed at runtime.eval ''inside theDBpackage — does not see the usual surrounding lexical scope but the scope of the first non-DBcaller. Only debugger authors hit this.XS load failures — some binary-interface problems during
requireof an XS module are fatal even insideeval, unless$ENV{PERL_DL_NONLAZY}is set. Version skew between the running interpreter and a pre-built.sois the common case. pperl does not load XS; the caveat applies wheneval’d code delegates loading to a classic perl5.
Differences from upstream#
Fully compatible with upstream Perl 5.42.
See also#
die— the counterpart: throws the exception thatevalcatches. The trailing-newline rule on the message shapes what lands in$@.do—do FILEreads and evaluates a file the way string eval reads and evaluates a string; useful for configuration files written in Perl.return— insideeval BLOCKreturns from the enclosing sub, not from the block; use a trailing expression to hand a value back from theevalitself.require— commonly wrapped inevalto probe for optional modules without aborting at compile time.evalbytes— string eval that treats its argument as a byte string and allows source filters to work normally; use when byte-level semantics matter.$@— where a caught exception lands, cleared to the empty string on successfuleval.$^S— tells$SIG{__DIE__}and$SIG{__WARN__}handlers whether anevalortryis currently active.$SIG{__DIE__}— pre-throw hook; fires even for exceptions an enclosingevalis about to catch, which is the usual reason tolocal-ize it for the duration of a trap.