Hint on local DIE handlers in Eval
Peter Skipworth
skip at peterskipworth.com
Thu Jan 9 22:56:33 CST 2003
Erm - u did :)
----- Original Message -----
From: "David Dick" <david_dick at iprimus.com.au>
To: "Scott Penrose" <scottp at dd.com.au>
Cc: <melbourne-pm at pm.org>
Sent: Friday, January 10, 2003 3:30 PM
Subject: Re: Hint on local DIE handlers in Eval
> Bugger, should have hit reply-all....
>
> David Dick wrote:
>
> > i've never actually used a DIE handler before. Why would you use
> > them? I understand that intercepting a exception thrown by a die and
> > informing the user about it in a graceful fashion is a useful
> > thing(tm), but i tend to use an eval block (or similar such as
> > Error.pm) around the suspect code and a test afterwards. Is the DIE
> > handler just another example of TIMTOWTDI, or does it have specific
> > advantages/disadvantages (not merely gotchas) associated with it?
> > -dave
> >
> > Scott Penrose wrote:
> >
> >> Thought I might share some wisdom on a common code error I have seen
> >> in my own code as well as others...
> >>
> >> DIE handlers are great to change so that you can gracefully tell the
> >> user. However you must remember that module writers tend to expect
> >> the die handler to actually do a die, and not an "print STDERR ...;
> >> exit 1;".
> >>
> >> It is common to find in module code things like...
> >> eval q{
> >> use Fred;
> >> };
> >> unless ($@) {
> >> print "Cool Fred exists on this machine";
> >> }
> >>
> >> but of course with the DIE handler set this may fail to pick up the
> >> error, calling your DIE handler and exiting, when it should have
> >> continued.
> >>
> >> You probably find yourself often writing code like this
> >>
> >> eval {
> >> local $SIG{__DIE__} = sub { die $_[0] };
> >> Do Stuff Here...
> >> };
> >> print "Errors checking here" if ($@);
> >>
> >> Which correctly picks up errors in the eval.
> >>
> >> So us smart developers start doing our own local DIE handler along
> >> the lines of...
> >>
> >> eval q{
> >> local $SIG{__DIE__} = sub { die $_[0] };
> >> use Fred;
> >> };
> >> unless ($@) {
> >> print "Cool Fred exists on this machine";
> >> }
> >>
> >> Of course the problem with our little bit of code above is that when
> >> perl compiles our string it has not yet set the local die handler. So
> >> any errors in compile (eg: Fred does not exist as a module) causes
> >> the root DIE handler to get called, again missing the error and not
> >> handling it correctly.
> >>
> >> So the correct approach is of course...
> >> {
> >> local $SIG{__DIE__} = sub { die $_[0] };
> >> eval q{
> >> use Fred;
> >> };
> >> unless ($@) {
> >> print "Cool Fred exists on this machine";
> >> }
> >> }
> >>
> >> (ie: move the local $SIG{__DIE__} outside the string eval, but inside
> >> a block).
> >>
> >> This may seem very obvious to some, but you would be surprised how
> >> many times I have seen it done and then cause REALLY obscure errors
> >> when upgrading a CPAN module (Cache::Cache uses the eval q{ use ...}
> >> approach to check for modules, and does NOT set a local DIE handler)
> >>
> >> :-)
> >>
> >> Scott
> >
> >
> >
>
>
More information about the Melbourne-pm
mailing list