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

According to warnings and perldiag it's possible to disable special warning classes in a lexical scope. (like the uninitialized one in the example)

Is it also possible to use this mechanism to disable my own debug messages for a scope?

(I'm aware about the possibility to manipulate $SIG{"__WARN__"} handler, but trying not to reinvent the wheel².)

use strict; use warnings; my $x; { no warnings; # no warnings 'uninitialized'; print "$x"; warn "inside"; } print "$x"; warn "outside";
inside at d:/Users/lanx/pm/no_warn.pl line 9. Use of uninitialized value $x in string at d:/Users/lanx/pm/no_warn.pl + line 11. outside at d:/Users/lanx/pm/no_warn.pl line 12.

Cheers Rolf
(addicted to the Perl Programming Language :)
Wikisyntax for the Monastery

²) and overusing Pad::Walker

Replies are listed 'Best First'.
Re: Using 'no warnings' to disable own debug warn(ing)s?
by LanX (Saint) on Jun 22, 2018 at 18:05 UTC
    haukex send my a /msg saying that he's traveling ATM and can't test, but suggests trying warnings::warnif . (see warnings for details)

    I suppose he means registering an own private warning classes, which sounds like a good idea, when using a custom wrapper function...

    update

    hmm ... no ... the wrapper would be in another scope ...

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery

      Well, my thinking was that since I've used warnings::register in my modules and warnings::warnif to create custom warnings, and that function is sensitive to FATAL warnings, I thought it'd be sensitive to no warnings as well, since AFAIK warn just unconditionally warns (and AFAIK the only way to catch it is with %SIG). And it does indeed work, but unfortunately it seems that it only works across package boundaries, I'm not entirely sure yet why, but from a quick look at the source it seems to be because it uses (parts of) Carp under the hood, looking up the call stack.

      use warnings; use strict; { package Foo; use warnings::register; sub bar { warnings::warnif("bar: $_[0]"); } } { no warnings; Foo::bar("inside"); } Foo::bar("outside"); use warnings::register; use Carp; { no warnings; warn "warn"; warnings::warn("warnings::warn"); carp "carp"; warnings::warnif("inside 2"); } warnings::warnif("outside 2"); __END__ bar: outside at w.pl line 17. warn at w.pl line 23. warnings::warn at w.pl line 24. carp at w.pl line 25.

      So at the moment my only two suggestions are to either go across package boundaries like I did in the above, or write your own debug function, which I tend to do. Just one example from here:

      sub _debug { my ($self, $lvl, @out) = @_; return if $self->{debug}<$lvl || !@out; print STDERR __PACKAGE__, " DEBUG: ", @out, "\n"; } # ... $self->_debug(2, ...);