Search code examples
perlsmartmatch

Why does @array ~~ LIST return false even though @array contains the same elements as LIST?


I have

@a = (1,2,3); print (@a ~~ (1,2,3))

and

@a = (1,2,3); print (@a == (1,2,3))

The first one is the one I expect to work, but it does not print anything. The second one does print 1.

Why? Isn't the smart matching operator ~~ supposed to match in the case of @a ~~ (1,2,3)?


Solution

  • For a second, lets consider the slightly different

    \@a ~~ (1,2,3)
    

    ~~ evaluates its arguments in scalar context, so the above is the same as

    scalar(\@a) ~~ scalar(1,2,3)
    
    • \@a (in any context) returns a reference to @a.
    • 1, 2, 3 in scalar context is similar to do { 1; 2; 3 }, returning 3.

    So minus a couple of warnings*, the above is equivalent to

    \@a ~~ 3
    

    What you actually want is

    \@a ~~ do { my @temp = (1,2,3); \@temp }
    

    which can be shortened to

    \@a ~~ [ 1,2,3 ]
    

    Finally, the magic of ~~ allows \@a to be written as @a, so that can be shortened further to

    @a ~~ [ 1,2,3 ]
    

    * — Always use use strict; use warnings;!