In the ~~ implementation, consistently use the SV-aware API for hash keys.
Rafael Garcia-Suarez [Sun, 24 May 2009 15:19:11 +0000 (17:19 +0200)]
This way, we can handle tied hashes such as ones that have references as keys.

pp_ctl.c
t/op/smartmatch.t

index e0c98ba..e12b671 100644 (file)
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -4159,12 +4159,11 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
               to check that one is a subset of the other. */
            (void) hv_iterinit(hv);
            while ( (he = hv_iternext(hv)) ) {
-               I32 key_len;
-               char * const key = hv_iterkey(he, &key_len);
+               SV *key = hv_iterkeysv(he);
                
                ++ this_key_count;
                
-               if(!hv_exists(other_hv, key, key_len)) {
+               if(!hv_exists_ent(other_hv, key, 0)) {
                    (void) hv_iterinit(hv);     /* reset iterator */
                    RETPUSHNO;
                }
@@ -4191,12 +4190,8 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
 
            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 not happen? */
-                   key = SvPV(*svp, key_len);
-                   if (hv_exists(hv, key, key_len))
+                   if (hv_exists_ent(hv, *svp, 0))
                        RETPUSHYES;
                }
            }
@@ -4241,12 +4236,8 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
 
            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 not happen? */
-                   key = SvPV(*svp, key_len);
-                   if (hv_exists(MUTABLE_HV(SvRV(d)), key, key_len))
+                   if (hv_exists_ent(MUTABLE_HV(SvRV(d)), *svp, 0))
                        RETPUSHYES;
                }
            }
index a7a33f7..5dfebbd 100644 (file)
@@ -11,6 +11,7 @@ no warnings 'uninitialized';
 
 use Tie::Array;
 use Tie::Hash;
+use Tie::RefHash;
 
 # Predeclare vars used in the tests:
 my @empty;
@@ -44,6 +45,9 @@ tie my %tied_hash, 'Tie::StdHash';
 our $ov_obj = Test::Object::WithOverload->new;
 our $obj = Test::Object::NoOverload->new;
 
+tie my %refh, 'Tie::RefHash';
+$refh{$ov_obj} = 1;
+
 my @keyandmore = qw(key and more);
 my @fooormore = qw(foo or more);
 my %keyandmore = map { $_ => 0 } @keyandmore;
@@ -251,6 +255,11 @@ __DATA__
 =      %hash           %tied_hash
        %tied_hash      %tied_hash
 !=     {"a"=>"b"}      %tied_hash
+       $ov_obj         %refh
+!      "$ov_obj"       %refh
+       [$ov_obj]       %refh
+!      ["$ov_obj"]     %refh
+       %refh           %refh
 
 #  - an array ref
 #  (since this is symmetrical, tests as well hash~~array)