Reputation: 10855
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)
?
Upvotes: 4
Views: 1251
Reputation: 132812
Start with What is the difference between a list and an array? in the perlfaq. It specifically shows you how your choice of values is wrong.
You might also start by writing out why you expected each to work or not work, so that we might correct your expectations. Why did you think you'd get the results that you expected?
As for the smart match bits, there's no rule for ARRAY ~~ LIST
. The smart match only works with the pairs enumerated in its table in perlsyn. It's going to force it to be one of those pairs.
When you run into these problems, try many more cases:
#!perl
use v5.10.1;
use strict;
use warnings;
my @a = (1,2,3);
say "\@a is @a";
say "\@a ~~ (1,2,3) is ", try( @a ~~ (1,2,3) );
say "\@a ~~ [1,2,3] is ", try( @a ~~ [1,2,3] );
say "\@a ~~ 3 is ", try( @a ~~ 3 );
say "3 ~~ \@a is ", try( 3 ~~ @a );
say '';
my @b = (4,5,6);
say "\@b is @b";
say "\@b ~~ (4,5,6) is ", try( @b ~~ (4,5,6) );
say "\@b ~~ [4,5,6] is ", try( @b ~~ [4,5,6] );
say "\@b ~~ 3 is ", try( @b ~~ 3 );
say "3 ~~ \@b is ", try( 3 ~~ @b );
say '';
say "\@b ~~ \@a is ", try( @b ~~ @a );
sub try { $_[0] || 0 }
The output of the various cases is the clue that you misread the docs:
Useless use of a constant (2) in void context at test.pl line 8.
Useless use of a constant (4) in void context at test.pl line 17.
Useless use of a constant (5) in void context at test.pl line 17.
@a is 1 2 3
@a ~~ (1,2,3) is 0
@a ~~ [1,2,3] is 1
@a ~~ 3 is 0
3 ~~ @a is 1
@b is 4 5 6
@b ~~ (4,5,6) is 0
@b ~~ [4,5,6] is 1
@b ~~ 3 is 0
3 ~~ @b is 0
@b ~~ @a is 0
Upvotes: 6
Reputation: 385887
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;
!
Upvotes: 12
Reputation: 5290
Smart match tries to do what I think you're expecting if you use an array or an array reference on the right side -- but not a list.
$ perl -E '@a = (1, 2, 3); say (@a ~~ (1, 2, 3))'
$ perl -E '@a = (1, 2, 3); say ((1, 2, 3) ~~ @a)' # also misguided, but different
1
$ perl -E '@a = (1, 2, 3); say (@a ~~ [1, 2, 3])'
1
Upvotes: 9