Re: smart match: array ~~ hash
Dmitry Karasik [Wed, 28 Nov 2007 21:49:59 +0000 (22:49 +0100)]
Message-ID: <20071128204959.GA68977@tetsuo.karasik.eu.org>

       plus more tests.

p4raw-id: //depot/perl@32559

pod/perlsyn.pod
pp_ctl.c
t/op/smartmatch.t

index 8468723..eb9fc4a 100644 (file)
@@ -674,7 +674,7 @@ order, determines the match behaviour.
     Any     Code[+]   scalar sub truth         $b->($a)
 
     Hash    Hash      hash keys identical      [sort keys %$a]~~[sort keys %$b]
-    Hash    Array     hash value slice truth   grep $_, @$a{@$b}
+    Hash    Array     hash slice existence     grep {exists $a->{$_}} @$b
     Hash    Regex     hash key grep            grep /$b/, keys %$a
     Hash    Any       hash entry existence     exists $a->{$b}
 
index 39f18b2..64157f3 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -4032,23 +4032,19 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
            AV * const other_av = (AV *) SvRV(Other);
            const I32 other_len = av_len(other_av) + 1;
            I32 i;
-           
-           if (HvUSEDKEYS((HV *) This) != other_len)
-               RETPUSHNO;
-           
-           for(i = 0; i < other_len; ++i) {
+
+           for (i = 0; i < other_len; ++i) {
                SV ** const svp = av_fetch(other_av, i, FALSE);
                char *key;
                STRLEN key_len;
 
-               if (!svp)       /* ??? When can this happen? */
-                   RETPUSHNO;
-
-               key = SvPV(*svp, key_len);
-               if(!hv_exists((HV *) This, key, key_len))
-                   RETPUSHNO;
+               if (svp) {      /* ??? When can this not happen? */
+                   key = SvPV(*svp, key_len);
+                   if (hv_exists((HV *) This, key, key_len))
+                       RETPUSHYES;
+               }
            }
-           RETPUSHYES;
+           RETPUSHNO;
        }
        else if (SM_OTHER_REGEX) {
            PMOP * const matcher = make_matcher(other_regex);
index 3c6d1c3..ed41aaa 100644 (file)
@@ -100,6 +100,12 @@ __DATA__
        \%::            [keys %main::]
 !      \%::            []
        {"" => 1}       [undef]
+       { foo => 1 }    ["foo"]
+       { foo => 1 }    ["foo", "bar"]
+       \%hash          ["foo", "bar"]
+       \%hash          ["foo"]
+!      \%hash          ["quux"]
+       \%hash          [qw(foo quux)]
 
 #  - a regex
        {foo => 1}      qr/^(fo[ox])$/
@@ -116,6 +122,7 @@ __DATA__
 !      []              [1]
        [["foo"], ["bar"]]      [qr/o/, qr/a/]
        ["foo", "bar"]          [qr/o/, qr/a/]
+!      ["foo", "bar"]          [qr/o/, "foo"]
        $deep1          $deep1
 !      $deep1          $deep2
 
@@ -158,3 +165,15 @@ __DATA__
 
        %hash           "foo"
        %hash           /bar/
+       %hash           [qw(bar)]
+!      %hash           [qw(a b c)]
+       %hash           %hash
+       %hash           {%hash}
+       %hash           %tied_hash
+       %tied_hash      %tied_hash
+       %hash           { foo => 5, bar => 10 }
+!      %hash           { foo => 5, bar => 10, quux => 15 }
+
+       @nums           {  1, '',  2, '' }
+       @nums           {  1, '', 12, '' }
+!      @nums           { 11, '', 12, '' }