perlsmartmatch

Why does smartmatch return true when comparing array slices that should be different?


The following script smart-matches slices of two arrays. At the start, both arrays are the same and I'm getting reasonable results. Then I change one of the arrays and smart-match two new slices, but it still says that the slices are identical. However, when I copy the slices into arrays, smart-matching the arrays shows that they are indeed different.

The script:

#!/usr/bin/perl
use warnings;
use strict;
use diagnostics;

my @x = qw (one two);
my @y = qw (one two);
my @x_s;
my @y_s;

print "Before change: values are the same:\n";
@x_s = @x[0,1];
@y_s = @y[0,1];
print "\@x_s: @x_s\n";
print +(@x[0,1] ~~ @y[0,1]) ? "equal\n" : "not equal\n";
print +(@x_s ~~ @y_s) ? "equal\n" : "not equal\n";

$x[0]='three';

print "After change: values should be different:\n";
@x_s = @x[0,1];
@y_s = @y[0,1];
print "\@x_s: @x_s\n";
print +(@x[0,1] ~~ @y[0,1]) ? "equal\n" : "not equal\n";
print +(@x_s ~~ @y_s) ? "equal\n" : "not equal\n";

The output:

Before change: values are the same:
@x_s: one two
equal
equal
After change: values should be different:
@x_s: three two
equal
not equal

I'm using Perl 5.10.1, and this happens for both array slices and hash slices. Why does this happen?


Solution

  • Looks like smart matching works in scalar context with slices.

    Consider the following code pieces:

    Your case:

    #!/usr/bin/perl
    
    my @foo = (1,2);
    my @bar = (3,4);
    print @foo[1,2] ~~ @bar[1,2] ? "Equal\n" : "Not equal\n";
    

    That's probably what you need:

    #!/usr/bin/perl
    
    my @foo = (1,2);
    my @bar = (3,4);
    print [ @foo[1,2] ] ~~ [ @bar[1,2] ] ? "Equal\n" : "Not equal\n";