Velocity Reviews - Computer Hardware Reviews

Velocity Reviews > Newsgroups > Programming > Perl > Perl Misc > eval and Try::Tiny

Reply
Thread Tools

eval and Try::Tiny

 
 
Tim McDaniel
Guest
Posts: n/a
 
      04-13-2012
Miscellaneous neepery on the subject of eval and Try::Tiny.

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

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

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

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

$try = try { die 'In try with larger catch' } catch { $error = $_; return };
print Data:umper->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...ib/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, http://www.velocityreviews.com/forums/(E-Mail Removed)
 
Reply With Quote
 
 
 
 
Rainer Weikusat
Guest
Posts: n/a
 
      04-13-2012
(E-Mail Removed) (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:umper->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...ib/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/perl5140delt...ption-Handling
 
Reply With Quote
 
 
 
 
Tim McDaniel
Guest
Posts: n/a
 
      04-13-2012
In article <(E-Mail Removed) >,
Rainer Weikusat <(E-Mail Removed)> wrote:
>(E-Mail Removed) (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, (E-Mail Removed)
 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a
 
      04-13-2012
(E-Mail Removed) (Tim McDaniel) writes:
> Rainer Weikusat <(E-Mail Removed)> 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.
 
Reply With Quote
 
Dr.Ruud
Guest
Posts: n/a
 
      04-14-2012
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
 
Reply With Quote
 
Rainer Weikusat
Guest
Posts: n/a
 
      04-14-2012
"Dr.Ruud" <(E-Mail Removed)> 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).

 
Reply With Quote
 
 
 
Reply

Thread Tools

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
to eval or not to eval? Marc Girod Perl Misc 2 04-19-2011 01:13 PM
eval('07') works, eval('08') fails, why? Alex van der Spek Python 6 01-08-2009 08:24 PM
Different behavior between eval "07" and eval "08" Liang Wang Perl Misc 8 02-02-2008 08:31 PM
DataBinder.Eval and Eval. craigkenisston@hotmail.com ASP .Net 1 06-16-2006 05:33 PM
DataBinder.Eval for an object's property property... like Eval(Container.DataItem,"Version.Major") Eric Newton ASP .Net 3 04-04-2005 10:11 PM



Advertisments