sid_com sid_com - 2 months ago 8
Perl Question

Can I replace the binding operator with the smartmatch operator in Perl?

How can I write this with the smartmatch operator (

~~
)?

use 5.010;

my $string = '12 23 34 45 5464 46';

while ( $string =~ /(\d\d)\s/g ) {
say $1;
}

Answer

If we go and look at what these two variants get transformed into, we can see the reason for this.


  • First lets look at the original version.

    perl -MO=Deparse -e'while("abc" =~ /(.)/g){print "hi\n"}'
    
    while ('abc' =~ /(.)/g) {
        print "hi\n";
    }
    

    As you can see there wasn't any changing of the opcodes.

  • Now if you go and change it to use the smart-match operator, you can see it does actually change.

    perl -MO=Deparse -e'while("abc" ~~ /(.)/g){print "hi\n"}'
    
    while ('abc' ~~ qr/(.)/g) {
        print "hi\n";
    }
    

    It changes it to qr, which doesn't recognize the /g option.

    This should probably give you an error, but it doesn't get transformed until after it gets parsed.


    The warning you should have gotten, and would get if you used qr instead is:

    syntax error at -e line 1, near "qr/(.)/g"


The smart-match feature was never intended to replace the =~ operator. It came out of the process of making given/when work like it does.

Most of the time, when(EXPR) is treated as an implicit smart match of $_.
...