http://qs1969.pair.com?node_id=736203

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

Is there a more succinct way of writing this?
my $foo;

eval { my $foo = bar->something() }; die $@ if $@;

return $foo;
i.e. catching and rethrowing an exception at the same time as returning the return value is no exceptions.

Replies are listed 'Best First'.
Re: eval and return values
by Bloodnok (Vicar) on Jan 14, 2009 at 12:41 UTC
    Your code wouldn't return anything since $foo is lexically re-declared in the assignment within the eval block (something that strictures would have warned you about).

    I think you probably meant something like...

    my $foo = eval { bar->something() }; die $@ if $@; $foo;

    Update:

    s/with/within/

    A user level that continues to overstate my experience :-))
      ... since $foo is lexically re-declared in the assignment within the eval block (something that strictures would have warned you about).
      No, that's kosher with warnings and strictures:
      >perl -wMstrict -le "sub S { return 'Something' } my $foo = 'bar'; eval { my $foo = S() }; die $@ if $@; print qq{after eval: $foo}; " after eval: bar
Re: eval and return values
by jplindstrom (Monsignor) on Jan 14, 2009 at 12:44 UTC
    First, remove the "my" inside the eval block, otherwise it won't do what you think it does.

    To me, as written, it's equivalent to:

    return bar->something();

    That's pretty succinct :)

    What is it that you really want to do? Log the error before rethrowing it?

    Having said that, this is a slightly more succinct way:

    my $foo = eval { bar->something() }; die if $@; # See "perldoc -f die" for what this does
    But note that if you call a method in between the eval and checking $@, any eval potentially called inside the method will reset $@ for you, so you need to capture the value of $@ immediately.

    Also note that other things may potentially mess up $@ for you (if an eval was used in a DESTROY block which was triggered by the exception). This is normally not a problem, but when something in your code changes and it becomes a problem it will confuse you for a bit because of the action at a distance.

    So overall it's better to make sure the eval returns a true value, and check for that. If an exception is thrown, eval returns undef (perldoc -f eval).

    /J

Re: eval and return values
by puudeli (Pilgrim) on Jan 14, 2009 at 12:44 UTC
Re: eval and return values
by JavaFan (Canon) on Jan 14, 2009 at 13:22 UTC
    I'd write that as:
    my $foo; eval {$foo = bar->something(); 1} or die "eval failed ($@)"; $foo;
    First, I don't 'my' $foo inside the block. Second, an eval may fail, yet leave $@ false (because of 'end of scope' effects). So you should make sure that on success, the eval returns a defined value, and check the return value of the eval.