Beefy Boxes and Bandwidth Generously Provided by pair Networks
Your skill will accomplish
what the force of many cannot
 
PerlMonks  

Disabling runtime warnings in dynamic scope?

by LanX (Cardinal)
on Apr 25, 2018 at 22:26 UTC ( #1213557=perlquestion: print w/replies, xml ) Need Help??

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

On request of a colleague I was playing around with an own implementation of switch as replacement for given/when

Surprisingly, I can use next within a sub to be able to fall thru to the next case, which leads to a nice syntax.

use strict; use warnings; use diagnostics; sub switch { no warnings 'exiting'; while (@_) { my ($case, $action) = splice @_,0,2; return $action->($case) if $_ ~~ $case; } } #no warnings 'exiting'; switch [1,2,3] => sub { print "bla" ; next}, 3 => sub { print "bla2" } for (3);

But I'm getting

Exiting subroutine via next at d:/Users/RolfLangsdorf/pm/switch.pl lin +e 18 (#1) (W exiting) You are exiting a subroutine by unconventional means, +such as a goto, or a loop control statement.

Obviously I can't dynamically disable the warning, because it's lexically scoped.

Uncommenting the #no warnings 'exiting' works, but would be acting for a much wider scope.

Question:

Is it possible to disable a certain warning in the dynamic scope?

Overwriting the warn handler does the trick ...

local $SIG{__WARN__} = sub { warn "$_[0]" unless $_[0] =~ /^Exiting subroutine via next/ } ;

... , but maybe there is a cleaner solution?

NB: this is experimental code and not meant for production! :)

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

Replies are listed 'Best First'.
Re: Disabling runtime warnings in dynamic scope? (no warnings 'exiting'; use warnings 'exiting';
by beech (Parson) on Apr 25, 2018 at 23:05 UTC

    Hi

    Find the right scope and tickle ${^WARNING_BITS}?

    $ perl -l #!/usr/bin/perl -- use strict; use warnings; use diagnostics; sub switch { no warnings 'exiting'; while (@_) { my ($case, $action) = splice @_,0,2; return $action->($case) if $_ ~~ $case; } } no warnings 'exiting'; switch [1,2,3] => sub { print "bla" ; next}, 3 => sub { print "bla2" } for (3); use warnings 'exiting'; switch [1,2,3] => sub { print "bla" ; next}, 3 => sub { print "bla2" } for (3); use warnings 'exiting'; switch [1,2,3] => sub { no warnings 'exiting'; print "bla" ; next}, 3 => sub { no warnings 'exiting'; print "bla2" } for (3); __END__ bla bla2 bla Exiting subroutine via next at - line 23 (#1) (W exiting) You are exiting a subroutine by unconventional means, +such as a goto, or a loop control statement. bla2 bla bla2
Re: Disabling runtime warnings in dynamic scope?
by choroba (Archbishop) on Apr 26, 2018 at 08:00 UTC
    Do you know Switch::Perlish? My patch is almost two years old, but I hope it still makes it work in the recent Perl.

    ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
      I've seen it. I'm experimenting on other ideas. ..

      Which patch for which problem?

      I can't see if I can easily replace the test condition to something different.

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

        The patch for the single problem reported in the distribution's bug tracker.

        ($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,
Re: Disabling runtime warnings in dynamic scope?
by shmem (Chancellor) on Apr 26, 2018 at 09:04 UTC
    Is it possible to disable a certain warning in the dynamic scope?

    Which scope is dynamic here? All scopes here are determined at compile time.

    but maybe there is a cleaner solution?

    The most obvious clean solutions are

    { no warnings 'exiting'; switch [1,2,3] => sub { print "bla" ; next}, 3 => sub { print "bla2" } for (3); }

    or

    switch [1,2,3] => sub { print "bla" ; { no warnings 'exiting'; next } }, 3 => sub { print "bla2" } for (3);

    or even

    sub goNext { no warnings 'exiting'; next } switch [1,2,3] => sub { print "bla" ; goNext }, 3 => sub { print "bla2" } for (3);

    perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'
      > All scopes here are determined at compile time.

      Only lexical aka static scopes.

      Eg local has a dynamic scope .

      Check the definitions.

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

        Only lexical aka static scopes.

        Eg local has a dynamic scope.

        <edit>
        Because of LanX answer below:

        Well, local has no scope at all - it just masks a (package) global at runtime until the localizing goes out of (lexical) scope, but that's just nitpicking at wording perhaps. See also my/local, space/time (was: Re: The difference between my and local).

        local has a static scope. Localized variables have a dynamic scope.
        </edit>

        But here you answered the question for yourself. The warning bits are compiled into each lexical scope at compile time, and a local $^W = $my_bits doesn't change them at runtime for scopes further down.

        So there are two possibilities:

        1. localize $SIG{__WARN__} to propagate a runtime behavior
        2. compile and eval code to be called with a current $^W at runtime
        perl -le'print map{pack c,($-++?1:13)+ord}split//,ESEL'

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: perlquestion [id://1213557]
Approved by stevieb
Front-paged by stevieb
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others having an uproarious good time at the Monastery: (4)
As of 2021-05-18 11:56 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    Perl 7 will be out ...





    Results (178 votes). Check out past polls.

    Notices?