Beefy Boxes and Bandwidth Generously Provided by pair Networks
Come for the quick hacks, stay for the epiphanies.
 
PerlMonks  

die hooks, signal handlers and eval, all mixed up

by Amoe (Friar)
on Nov 30, 2001 at 22:51 UTC ( [id://128708]=perlquestion: print w/replies, xml ) Need Help??

Amoe has asked for the wisdom of the Perl Monks concerning the following question:

Hey.

I was browsing through the perldocs and saw this thing called $SIG{__DIE__}, which looked quite cool. In my script I had already implemented by redirecting STDERR to a file with magic open, but my one problem with this was that dies got printed to the logfile also, and not to the screen. I wanted them to go to both the screen and the logfile. So I thought, "COOL", and quickly added this line:

$SIG{__DIE__} = sub { print @_; die @_ };

Run it, everything was cool for a while. Then suddenly, alas. My code depends on some modules (the cause seems to be the URI module), and my __DIE__ handler was getting invoked by a module - inside an eval, that's why I never saw it before. die knows not to print it because it's being caught. print doesn't.

My guess is that I'll have to find an alternate way to do this. If so, can anyone suggest one? Or is there some way (hopefully not too magical) that I can find out whether my __DIE__ hook got called from inside an eval? It seems to me that a more effective design for this hook would be to make it not get called at all if it was inside one.

Thanks, Amoe.

--
my one true love

Replies are listed 'Best First'.
(tye)Re: die hooks, signal handlers and eval, all mixed up
by tye (Sage) on Dec 01, 2001 at 00:20 UTC

    Personally, I suggest you don't use $SIG{__DIE__} and instead use eval. I find the whole design of $SIG{__DIE__} to be flawed. It can be useful in limited circumstances but it can't scale well and I find it best to just avoid it.

    But, if you do use $SIG{__DIE__}, then you need to know about $^S: "True if inside an eval(), otherwise false." so you can do:

    $SIG{__DIE__}= sub { die @_ if $^S; # rest of code here };
    for example.

    Update: How do you replace $SIG{__DIE__} with eval, you ask?

    $SIG{__DIE__}= sub { die @_ if @^S; doStuffWith( $_[0] ); }; doEverythingElse(); exit 0;
    becomes
    eval { doEverythingElse(); 1; } or do { doStuffWith( $@ ); }; exit 0;
    or thereabouts.

            - tye (but my friends call me "Tye")
Re: die hooks, signal handlers and eval, all mixed up
by Zaxo (Archbishop) on Nov 30, 2001 at 23:00 UTC

    Well-placed,

    { local $SIG{__DIE__} = sub { print @_; die @_ }; # ... }
    may be what you need.

    After Compline,
    Zaxo

Re: die hooks, signal handlers and eval, all mixed up
by IlyaM (Parson) on Dec 01, 2001 at 02:33 UTC
    As tye already said you should better use eval. I fully agree with him.

    If you fill that you really need DIE handler (actually very unlikely) you can try to use well-placed localized DIE handlers as suggested Zaxo (i.e. in scopes where you do not call any modules - which limits seriously applicability of this advice) but probably it is better to use module Sig::PackageScoped which allows to do completly crazy things like package scoped DIE and WARN handlers. If you will use this module be sure to pay attention to its docs

    --
    Ilya Martynov (http://martynov.org/)

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://128708]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (1)
As of 2024-04-18 23:28 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found