From: Rafael Garcia-Suarez Date: Sun, 24 May 2009 15:19:11 +0000 (+0200) Subject: In the ~~ implementation, consistently use the SV-aware API for hash keys. X-Git-Url: http://git.shadowcat.co.uk/gitweb/gitweb.cgi?a=commitdiff_plain;h=b15feb55e45b2354be3659a613d28786b2518244;p=p5sagit%2Fp5-mst-13.2.git In the ~~ implementation, consistently use the SV-aware API for hash keys. This way, we can handle tied hashes such as ones that have references as keys. --- diff --git a/pp_ctl.c b/pp_ctl.c index e0c98ba..e12b671 100644 --- 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; } } diff --git a/t/op/smartmatch.t b/t/op/smartmatch.t index a7a33f7..5dfebbd 100644 --- a/t/op/smartmatch.t +++ b/t/op/smartmatch.t @@ -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)