http://qs1969.pair.com?node_id=377570

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

I have a testing routine which, as part of the test, calls a function in a way that generates a warning message. I am expeting this warning message and would like to supress it in order to have clean test output. However I only want to supress the warning message for this instance of the function call and I want to keep any other error messages that might occour.

I have tried using the 'no warnings qw/type/' pragma but have run into what seems to be a block nesting problem. According to perllexwarn the warnings pragma works on a block level which is fine. My problem seems to be when trying to control runtime warnings the scope doesn't work as I'm expecting:
#!/bin/perl use warnings::register; use warnings; printf( "Perl Version: %vd\n",$^V); test_warnings(); sub GenerateWarning { warn "warnings are ", warnings::enabled() ? "" : "not ", "enabled\n"; } sub test_warnings { no warnings; GenerateWarning(); AnotherSub(); } sub AnotherSub { GenerateWarning(); }
Produces the output:
Perl Version: 5.6.1 warnings are not enabled warnings are enabled
What I would like is for warnings to be not enabled both times. Is there a way to do what I want to do? Should I be doing this a different way?

Replies are listed 'Best First'.
Re: Nested runtime warning disabling
by ccn (Vicar) on Jul 26, 2004 at 20:46 UTC

    warnings have lexical scope, so

    no warnings; sub test_warnings { GenerateWarning(); AnotherSub(); } sub AnotherSub { GenerateWarning(); }

    also, may be this code be useful for you

    sub test_warnings { local $SIG{__WARN__} = sub {}; GenerateWarning(); AnotherSub(); }
      The problem with moving the 'no warnings' outside the test_warnings sub is that I will not get warnings when I call:
      sub another_test { AnotherSub(); }
      The local signal handler might work if I can just catch the class of error I'm trying to supress and 'pass through' everything else as normal.
Re: Nested runtime warning disabling
by gaal (Parson) on Jul 26, 2004 at 20:42 UTC
    Hackish, but you could use Hook::LexWrap to surround your GenerateWarning() with a wrapper that does no warnings;.
      Thanks. I tried out Hook::LexWrap
      use Hook::LexWrap; sub test_warnings { my $lexical = wrap 'GenerateWarning', pre => sub { no warnings }; GenerateWarning(); AnotherSub(); }
      This does produce the result I was looking for, but I agree it is a little hackish.

      Does anyone have a more elegant solution?