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