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

I can change the behavior of warn by assigning a sub ref to $SIG{__WARN__}. And if I want to put it back to the default bahavior, I can do a
$SIG{__WARN__}='DEFAULT';
But suppose another module also changes the behavior of warn by assigning its own sub ref to $SIG{__WARN__}. Then, one assignment overwrites the other. Wouldn't it be friendlier to save the current warn subroutine and call it within your warn subroutine? And instead of just setting the warning back to the default behavior, why not put the preceding warn routine back? Has anyone tried to do this? If so, do you have an elegant solution?

Replies are listed 'Best First'.
Re: signal handlers that play nice
by dragonchild (Archbishop) on Oct 27, 2005 at 13:40 UTC
    local $SIG{__WARN__} = sub { ... };
    Much better, cleaner, and you have the compiler handle silly stuff like replacing the old one for you.

    My criteria for good software:
    1. Does it work?
    2. Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
      It is not immediately obvious how you would call the previous warn routine within your subroutine.
Re: signal handlers that play nice
by Tanktalus (Canon) on Oct 27, 2005 at 14:47 UTC

    You may want to check out Automatic stack tracebacks in warnings? on how I replace a warn handler and place a new warn handler in the "stack" by calling the old warn handler during my warn handler. It's one of the few times where using & to call a function is the right WTDI since I want to transparently pass along all parameters. Now that I'm looking at it, the if modifier probably should also be checking that $oldwarn is a CODE ref...

    As for it being temporary - dragonchild's local suggestion is bang on. He just missed the part where you wanted to call the previous warn subroutine from within your own.

      typically you don't want to call any previously assigned routine; unless you are certain that its' code is kosher.
      the hardest line to type correctly is: stty erase ^H
        I'm not seeing the harm here. If you call the previous warn within your warn, you can't make things worst. If the previous warn works, your warn should still work. If it bombs, well the new warn still bombs. Inversely, if you don't call the previous warn, you may make another part of the program malfunction.
      You summed up the situation very well. Thanks!