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