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

I would like to suppress some warnings that I know will be generated in user supplied callback code.

Ie. I thought that the no warnings statement at point A in the code below would avoid the need to do it (commented out) in the callback code, but it doesn't.

Is there some way to do this? $^H manipulations or some such?

#! perl -slw use strict; sub test (&) { my $code = shift; { no warnings 'uninitialized'; ## A $code->( undef ); } } test { # no warnings 'uninitialized'; print "@_" };

I can suppress all warnings using $^W, but I'd rather just stop the ones I know will occur and leave the rest as diagnostics for the callers code.


Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.

Replies are listed 'Best First'.
Re: Imposing no warnings xxx upon callback code?
by ikegami (Patriarch) on Dec 22, 2006 at 16:14 UTC

    I can suppress all warnings using $^W

    No, warnings overrides $^W/-w (regardless of their relative order).

    use warnings; BEGIN { $^W = 0; } my $s = '' . undef(); # Use of uninitialized value

    Not just use warnings;. no warnings; overrides $^W/-w too (regardless of their relative order).

    no warnings; BEGIN { $^W = 1; } my $s = '' . undef(); # [No warnings]

    In the context of your problem, $^W won't work if the sub was compiled with use warnings; in effect.

    use strict; use warnings; sub test (&) { my $code = shift; local $^W = 0; $code->( undef ); } test { print "@_"; # Use of uninitialized value };

    That leaves you with $SIG{__WARN__}. You can catch the warnings and filter out the ones you don't want.

    Update: Adjusted formatting for coherence. Added example to show that no warnings; overrides $^W too.

      No, warnings overrides $^W/-w (regardless of their relative order).

      Of course. I knew there was a good reason for not using warnings :)

      $SIG{__WARN__} achieves my goal. Thankyou.


      Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
      Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
      "Science is about questioning the status quo. Questioning authority".
      In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Imposing no warnings xxx upon callback code?
by SFLEX (Chaplain) on Dec 22, 2006 at 16:37 UTC
    This maybe a way that can help you remove some warning you dont want.

    # remove unwanted warnings $SIG{__WARN__} = sub { my $wn = shift; return if $wn =~ /Use of uninitialized value/i; #Most annoying return if $wn =~ /name "(?:.+?)" used only once/i; #Very annoying warn $wn; };

    Good Luck!

    Updated: I have updated the code above "$SIG{__DIE__}" to "$SIG{__WARN__}". Sorry for any problems.

      As I fruitlessly tried to explain to you privately, $SIG{__DIE__} is not appropriate here. $SIG{__WARN__} is required. Maybe if I post a test you can run...

      use strict; use warnings; $SIG{__DIE__} = sub { my $wn = shift; return if $wn =~ /Use of uninitialized value/i; #Most annoying return if $wn =~ /name "(?:.+?)" used only once/i; #Very annoying warn $wn; }; print 123 + undef, "\n"; # We want to hide this warning. print 123 + 'abc', "\n"; # We want to see this warning.

      outputs

      Argument "abc" isn't numeric in addition (+) at 591379.pl line 12. Use of uninitialized value in addition (+) at 591379.pl line 11. 123 123

      If you change $SIG{__DIE__} to $SIG{__WARN__}, you get the desired output.

      Argument "abc" isn't numeric in addition (+) at 591379.pl line 12. 123 123

      Update: Regarding your update, $SIG{} = sub { ... }; is no good either. It's a syntax error.

        ya, I can be wrong!
        $SIG{__WARN__} = sub { my $wn = shift; return if $wn =~ /Use of uninitialized value/i; #Most annoying return if $wn =~ /name "(?:.+?)" used only once/i; #Very annoying warn $wn; };

        Good Luck!