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

I have a question about eval.

Given the general error handling construct:

perl -e '$foo = "foo"; eval { $bar = $foo; } or do { die "Error: $@"; };'

This works as expected (IE does not die) for any value of $foo except undef or empty string. If $foo is undef or empty string, $@ gets set to empty string and the or do {...} block is executed. This seems like the Wrong Thing to me -- assigning either undef or an empty string to a scalar is a valid statement, therefore $@ should not get set

It's easy enough to work around this (mis-)behavior by putting a no-op at the end of the eval block:

perl -e '$foo = undef; eval { $bar = $foo; 1; } or do { die "Error: $@"; };'

Still, I'm curious as to why it works this way. It doesn't seem to be consistent.

Replies are listed 'Best First'.
Re: Eval, assignments, and empty string/undef
by ikegami (Patriarch) on Mar 25, 2010 at 16:24 UTC

    This works as expected (IE does not die) for any value of $foo except undef or empty string.

    It did not die for those either.

    therefore $@ should not get set

    Why do you say that? It always gets set, either to the caught exception or to undef.

    It's easy enough to work around this (mis-)behavior by putting a no-op at the end of the eval block:

    It's not a no-op, it's an expression that returns a true value.

    I'm curious as to why it works this way.

    Confused about what a function is returning? Check the docs! eval is like a sub. The last value evaluated is returned.

Re: Eval, assignments, and empty string/undef
by BrowserUk (Patriarch) on Mar 25, 2010 at 16:33 UTC
    This works as expected (IE does not die) for any value of $foo except undef or empty string

    It would also fail for $foo = 0; ## 0.0, '0' etc.. Also, your or do{ die ... }; could simply be or die...; if you've nothing else to do before you die.


    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.
      best if statement ever.
Re: Eval, assignments, and empty string/undef
by meredith (Friar) on Mar 26, 2010 at 13:57 UTC

    Building on what the fellows above said, eval works like a sub and will return the result of the last expression if not given an explicit return value. This means that when used with an 'or' operator, your eval will be false for any value of $foo that is false. It's not returning success or failure of the eval operation - this allows you to squeeze an eval into just about any code you want and you don't have to jump through hoops rearranging that code in order to catch an error.

    Instead, eval sets $@ to either undef or an error each time it's called, so you can test if the eval failed using 'if ($@) {...}' on the next line.

    perl -e '$foo = undef; eval { $bar = $foo; }; die "Error: $@" if $@;'
    mhoward - at - hattmoward.org