Hint on local DIE handlers in Eval
David Dick
david_dick at iprimus.com.au
Thu Jan 9 22:55:41 CST 2003
don't worry about me...... i'm _ok_..... *zonk*
Peter Skipworth wrote:
>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