Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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)?

like image 475
Qiang Li Avatar asked Nov 27 '22 18:11

Qiang Li


2 Answers

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;!

like image 138
ikegami Avatar answered Dec 10 '22 01:12

ikegami


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
like image 34
Jim Davis Avatar answered Dec 10 '22 01:12

Jim Davis