perl

How to mute that when and given are experimental in Perl?


I am migrating an old toolchain to a new system and now I get plenty of notifications given is experimental or when is experimental.

$ perl -e 'use v5.10; given (12) { when (12) { print "Hello World" }}'
given is experimental at -e line 1.
when is experimental at -e line 1.
Hello World

I would like my new system to be fully compatible with the old one. By this I mean the exact same output.

Is there a way to mute these notifications without touching the oneliners nor the scripts?


Solution

  • First of all, note that smartmatching will be removed in 5.42.


    To use given+when without warnings, one needs the following:

    # 5.10+
    use feature qw( switch );
    no if $] >= 5.018, warnings => qw( experimental::smartmatch );
    

    or

    # 5.18+
    use feature qw( switch );
    no warnings qw( experimental::smartmatch );
    

    experimental provides a shortcut for those two statements.

    use experimental qw( switch );
    

    Finally, you ask how to add this to your programs without changing them (and presumably without changing Perl). That leaves monkeypatching.

    I wouldn't recommend it. It's far easier to write a couple of one-liners to automatically fix up your programs than rewriting Perl's behaviour on the fly.

    But if you want to go in that direction, the simplest solution is probably to write a $SIG{__WARN__} handler that filters out the undesired warnings.

    $SIG{__WARN__} = sub {
       warn($_[0]) if $_[0] !~ /^(?:given|when) is experimental at /;
    };
    

    (Of course, that won't work if your program makes use of $SIG{__WARN__} already.)

    To get it loaded without changing your programs or one-liners, all you have to do is place the patch in a module, and tell Perl to load the module as follows:

    export PERL5OPT=-MMonkey::SilenceSwitchWarning
    

    $ cat Monkey/SilenceSwitchWarning.pm
    package Monkey::SilenceSwitchWarning;
    
    use strict;
    use warnings;
    
    $SIG{__WARN__} = sub {
        warn($_[0]) if $_[0] !~ /^(?:given|when) is experimental at /;
    };
    
    1;
    
    $ perl -e 'use v5.10; given (12) { when (12) { print "Hello World\n" }}'
    given is experimental at -e line 1.
    when is experimental at -e line 1.
    Hello World
    
    $ export PERL5OPT=-MMonkey::SilenceSwitchWarning
    
    $ perl -e 'use v5.10; given (12) { when (12) { print "Hello World\n" }}'
    Hello World