eval and Try::Tiny

Discussion in 'Perl Misc' started by Tim McDaniel, Apr 13, 2012.

  1. Tim McDaniel

    Tim McDaniel Guest

    Miscellaneous neepery on the subject of eval and Try::Tiny.

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    #! /usr/bin/perl
    use strict;
    use warnings;
    use Try::Tiny;
    use Data::Dumper;

    my $eval = eval {die 'In eval'};
    print Data::Dumper->Dump([$eval, $@], [qw[eval error]]), "\n=====\n";

    my $error = '';
    my $try = try { die 'In try with naive catch' } catch { $error = $_; };
    print Data::Dumper->Dump([$try, $error], [qw[try error]]), "\n=====\n";

    $try = try { die 'In try with larger catch' } catch { $error = $_; return };
    print Data::Dumper->Dump([$try, $error], [qw[try error]]), "\n";
    exit 0;

    Output:

    $ perl local/test/052.pl
    $eval = undef;
    $error = 'In eval at local/test/052.pl line 7.
    ';

    =====
    $try = 'In try with naive catch at local/test/052.pl line 11.
    ';
    $error = 'In try with naive catch at local/test/052.pl line 11.
    ';

    =====
    $try = undef;
    $error = 'In try with larger catch at local/test/052.pl line 14.
    ';


    Indeed, checking the code as of 5.8.8, and the most recent source
    under http://search.cpan.org/~doy/Try-Tiny-0.11/lib/Try/Tiny.pm, catch
    is invoked with

    for ($error) {
    return $catch->($error);
    }

    (I think it's stupid as all hell, but whatever.) So I think I can
    replace

    some_lhs = eval { body };
    # uses of $@

    with

    my $error;
    some_lhs = try { body } catch { $error = $_; return };
    # uses of $error

    Is that right?

    ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

    I've run across cases of

    eval string_value

    that I want to replace. Since the code for Try::Tiny localizes $@,
    I think I can get away with

    try { eval string_value; die $@ if $@ } catch { $error = $_; return }

    Anyone see a problem with that?

    --
    Tim McDaniel,
    Tim McDaniel, Apr 13, 2012
    #1
    1. Advertising

  2. (Tim McDaniel) writes:
    > Miscellaneous neepery on the subject of eval and Try::Tiny.


    [...]


    > my $error = '';
    > my $try = try { die 'In try with naive catch' } catch { $error = $_; };
    > print Data::Dumper->Dump([$try, $error], [qw[try error]]), "\n=====\n";


    [...]

    > $try = 'In try with naive catch at local/test/052.pl line 11.
    > ';
    > $error = 'In try with naive catch at local/test/052.pl line 11.
    > ';


    [...]

    > Indeed, checking the code as of 5.8.8, and the most recent source
    > under http://search.cpan.org/~doy/Try-Tiny-0.11/lib/Try/Tiny.pm, catch
    > is invoked with
    >
    > for ($error) {
    > return $catch->($error);
    > }
    >
    > (I think it's stupid as all hell, but whatever.)


    The idea behind that is obviously that the catching subroutine might
    be able to handle the error (Perl still supports real exception
    objects) and should thus have the option to inform the caller that no
    error occurred.

    > So I think I can
    > replace
    >
    > some_lhs = eval { body };
    > # uses of $@
    >
    > with
    >
    > my $error;
    > some_lhs = try { body } catch { $error = $_; return };
    > # uses of $error
    >
    > Is that right?


    You can also insert a system('perl -c "sleep(86400);"') in
    any place there and the result will be that the working code
    still works, just in a less efficient way. Actually, using the
    sleep-invocation is a much more efficient way to burn time than
    downloading $random_crap from CPAN whose only purpose is to "work
    around" what some guy didn't understand about Perl exception handling
    in particular and the concept of using exceptions for error handling in
    general. You don't even have to take my word for that, it's also all
    spelled out in the Perl 5.14.0 release notes available here:

    http://perldoc.perl.org/perl5140delta.html#Exception-Handling
    Rainer Weikusat, Apr 13, 2012
    #2
    1. Advertising

  3. Tim McDaniel

    Tim McDaniel Guest

    In article <>,
    Rainer Weikusat <> wrote:
    > (Tim McDaniel) writes:
    >> [Try::Tiny: catch returns a value]
    >> (I think it's stupid as all hell, but whatever.)

    >
    >The idea behind that is obviously that the catching subroutine might
    >be able to handle the error (Perl still supports real exception
    >objects) and should thus have the option to inform the caller that no
    >error occurred.


    Good point. It just makes it a touch annoying for *my particular*
    case, a drop-in replacement for eval, but I quite take your point
    about other cases.

    >all spelled out in the Perl 5.14.0 release notes available here:


    My workplace is on an older version of Perl, I can't upgrade it, and I
    don't know when they'll upgrade.

    >Actually, using the sleep-invocation is a much more efficient way to
    >burn time than downloading $random_crap from CPAN


    Try::Tiny is a long-standing package and not uncommon package, hardly
    "random crap".

    >whose only purpose is to "work around" what some guy didn't
    >understand about Perl exception handling in particular and the
    >concept of using exceptions for error handling in general.


    What do I do to use raw Perl to get reliable exceptions in older Perls?

    --
    Tim McDaniel,
    Tim McDaniel, Apr 13, 2012
    #3
  4. (Tim McDaniel) writes:
    > Rainer Weikusat <> wrote:


    [...]


    >>all spelled out in the Perl 5.14.0 release notes available here:

    >
    > My workplace is on an older version of Perl, I can't upgrade it, and I
    > don't know when they'll upgrade.


    In this case, this text provides some nice documentation regarding
    what the actual gotchas with eval and $@ are. There are two possible
    problem cases: Provided that object destructors are executed during
    exception unwinding occurring while existing from the eval,

    - $@ will be cleared when code running from a destructor calls
    eval

    - $@ will be overwritten when code running from such a
    destructor throws an exception itself

    Both issues can be avoided by adding a local $@ at the start of all
    destructors which might either die or use eval.

    >>Actually, using the sleep-invocation is a much more efficient way to
    >>burn time than downloading $random_crap from CPAN

    >
    > Try::Tiny is a long-standing package and not uncommon package, hardly
    > "random crap".


    The copyright notice says 2009 which means it is a good fourteen years
    younger than the facility it is supposed to fix. And neither "it is
    old" (which it isn't) nor "many people like it" are indicators for any
    particular technical quality.
    Rainer Weikusat, Apr 13, 2012
    #4
  5. Tim McDaniel

    Dr.Ruud Guest

    On 2012-04-13 18:57, Tim McDaniel wrote:

    > eval string_value; die $@ if $@


    That should be written as:

    eval "$string; 1" or die $@ || 'zombie error';

    --
    Ruud
    Dr.Ruud, Apr 14, 2012
    #5
  6. "Dr.Ruud" <> writes:
    > On 2012-04-13 18:57, Tim McDaniel wrote:
    >
    >> eval string_value; die $@ if $@

    >
    > That should be written as:
    >
    > eval "$string; 1" or die $@ || 'zombie error';


    Depending on the contents of $string, this may either clobber the
    result evaluating the code (because the eval will always return 1 if
    no error occurred and the string didn't cause a return) or cause a
    gratuitious failure (if $string contains a 'return $something' and this
    $something can be zero).
    Rainer Weikusat, Apr 14, 2012
    #6
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. bienwell
    Replies:
    4
    Views:
    3,761
    bienwell
    May 27, 2005
  2. DataBinder.Eval and Eval.

    , Jun 16, 2006, in forum: ASP .Net
    Replies:
    1
    Views:
    542
    Karl Seguin [MVP]
    Jun 16, 2006
  3. =?Utf-8?B?QUo=?=

    When to TRY and not to TRY

    =?Utf-8?B?QUo=?=, Oct 16, 2007, in forum: ASP .Net
    Replies:
    2
    Views:
    325
    sloan
    Oct 17, 2007
  4. Texas Bob
    Replies:
    0
    Views:
    224
    Texas Bob
    Jul 25, 2009
  5. Liang Wang
    Replies:
    8
    Views:
    129
    Ben Morrow
    Feb 2, 2008
Loading...

Share This Page