user907860 user907860 - 1 year ago 46
Perl Question

Why is @array ~~ $number different from @array == $number?

According to Programming Perl, using smartmatch with "any" on the left and a number on the right checks numeric equality:

| Left | Right | Description | Like (But Evaluated in Boolean Context) |
| Any | Num | Numeric equality | Any == Num |

Therefore, I expect the following to output

my @arr = ('aaa');
my $num = 1;
say @arr ~~ $num;

but it actually outputs the empty string.

I thought
would be converted to scalar
because it has 1 element, so
say @arr ~~ $num
would be equivalent to
say @arr == $num

Why is
@arr ~~ $num
different from
@arr == $num

Answer Source

The smartmatch operator obviously doesn't take lists as operands. As such, it evaluates its operands in scalar context. If that was the end of the story, the following wouldn't work

my @a = ('aaa', 'bbb');
my $s = 'aaa';
say $s ~~ @a;

because it would be the same as

say 'aaa' ~~ 2;

But it's clear that it does work. That's because smartmatch automatically creates a reference to its operands that are arrays or hashes, just like push does to its first operand. That means

say $s ~~ @a;

is really

say $s ~~ \@a;

and (your code)

say @a ~~ $n;

is the same as

say \@a == $n;

You need to get the length explicitly. The following will do what you want:

say 0+@a ~~ $n;

Of course, so would

say 0+@a == $n;

or even

say @a == $n;