( My apologies if this is a settled question; I'm
just looking for confirmation one way or the other. )
Per its perldelta, v5.14 fixes a slew of $@-handling bugs. So does that
obsolete the non-core Try::Tiny CPAN module? As far as I can tell, it's
just a workaround for [now-fixed(?)] bugs in the core.
There's a lot of buzz pretending you must never use eval{}, so I'd like
to know whether there's any substance to it. It sounds like cargo-cult
programming to me, because they never explain why, just tell you to
always use Try::Tiny and never use the core builtin. If this remains
true, I'd please like to know the particulars that still apply.
That module's manpage alleges:
There a number of issues with "eval".
* Clobbering $@
* Localizing $@ silently masks errors
* $@ might not be a true value
Yet the v5.14 perldelta reassuringly remarks:
Exception Handling
To make them more reliable and consistent, several changes
have been made to how "die", "warn", and $@ behave.
[...]
And v5.14's perlsub indeed reads:
The interesting thing about "&" is that you can generate new syntax
with it, provided it's in the initial position:
sub try (&@) {
my($try,$catch) = @_;
eval { &$try };
if ($@) {
local $_ = $@;
&$catch;
}
}
sub catch (&) { $_[0] }
try {
die "phooey";
} catch {
/phooey/ and print "unphooey\n";
};
That prints "unphooey". (Yes, there are still unresolved issues
having to do with visibility of @_. I'm ignoring that question for
the moment. (But note that if we make @_ lexically scoped, those
anonymous subroutines can act like closures... (Gee, is this
sounding a little Lispish? (Never mind.))))
Is that perlsub code still "wrong" in some way? In other words, is the
core's eval still considered too broken to use? Must one truly use a
non-core CPAN module for something so fundamental to core functionality
as exception handling? If so, that seems wrong to me.
It also reminds me of Rob Pike's statement that these "patterns" people
(in)famously develop are really just bug workarounds. Better to fix the
bugs than promote a "pattern", as we once did with while(defined($_ = <>)).
Thanks for your help,
--tom
Thread Next