1

In the following code, why does the first smartmatch fail to match and give the warning Argument "two" isn't numeric in smart match, while the second smartmatch works as expected (it matches)?

use strict;
use warnings;
use feature 'say';

my %h = ("one" => "un", "two" => "deux");
my $v = "two";
my @keys_h = keys %h;

say "matches first form"  if $v ~~ keys %h; # warning, doesn't match
say "matches second form" if $v ~~ @keys_h; # no warning, matches

I realize I could just use

$v ~~ %h

but I'd like to know why the first smartmatch doesn't work as I expect it to. I'm using Perl 5.10.1.

ThisSuitIsBlackNot
  • 23,492
  • 9
  • 63
  • 110
Rekr
  • 35
  • 3
  • 1
    Never, ever, ever again post a partial error message when asking a question. Always post the entire error message. – TLP Aug 14 '13 at 23:01

1 Answers1

4

Because an array and a list are not the same thing.

$v ~~ @keys_h

is matching a scalar against an array, (Any vs Array in the smart match behavior chart) returning true if the scalar matches an element of the array.

$v ~~ keys %h

is matching a scalar against a list. There is no rule for matching against a list, so the list is evaluated in scalar context, like

$v ~~ scalar(keys %h)

which resolves to

"two" ~~ 2

which is now a numeric comparison (Any vs. Num), which triggers the warning.

$v ~~ [ keys %h ]

would do what you want it to do, too.

mob
  • 117,087
  • 18
  • 149
  • 283