summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--pod/perlsyn.pod33
-rw-r--r--pp_ctl.c6
-rw-r--r--t/op/smartmatch.t8
3 files changed, 26 insertions, 21 deletions
diff --git a/pod/perlsyn.pod b/pod/perlsyn.pod
index 2e1f4c57d2..52a3f87c24 100644
--- a/pod/perlsyn.pod
+++ b/pod/perlsyn.pod
@@ -683,42 +683,43 @@ entries apply in those cases.
(overloading trumps everything below)
- Hash CodeRef sub truth for each key !grep { !$b->($_) } keys %$a
- Array CodeRef sub truth for each elt !grep { !$b->($_) } @$a
- Any CodeRef scalar sub truth $b->($a)
+ Hash CodeRef sub truth for each key[1] !grep { !$b->($_) } keys %$a
+ Array CodeRef sub truth for each elt[1] !grep { !$b->($_) } @$a
+ Any CodeRef scalar sub truth $b->($a)
Hash Hash hash keys identical [sort keys %$a]~~[sort keys %$b]
Array Hash hash slice existence @$a == grep {exists $b->{$_}} @$a
- Regex Hash hash key grep grep /$a/, keys %$b
+ Regex Hash hash key grep[1] grep /$a/, keys %$b
undef Hash always false (undef can't be a key)
Any Hash hash entry existence exists $b->{$a}
- Hash Array hash slice existence @$b == grep {exists $a->{$_}} @$b
- Array Array arrays are comparable[1]
- Any Array match against an array element[2]
+ Hash Array hash slice existence[1] @$b == grep {exists $a->{$_}} @$b
+ Array Array arrays are comparable[2]
+ Any Array match against an array element[3]
grep $a ~~ $_, @$b
Hash Regex hash key grep grep /$b/, keys %$a
Array Regex array grep grep /$b/, @$a
Any Regex pattern match $a =~ /$b/
- Num Range[3] in numeric range
- undef Range[3] always false
- Any Range[3] in string range
+ Num Range[4] in numeric range
+ undef Range[4] always false
+ Any Range[4] in string range
- Num numish[4] numeric equality $a == $b
+ Num numish[5] numeric equality $a == $b
Any Str string equality $a eq $b
Any Num numeric equality $a == $b
Any Any string equality $a eq $b
- 1 - that is, each element matches the element of same index in the other
- array. [2]
- 2 - If a circular reference is found, we fall back to referential equality.
- 3 - a range is written EXPR..EXPR (using the C<..> range operator, but
+ 1 - empty hashes or array won't match.
+ 2 - that is, each element matches the element of same index in the other
+ array. [3]
+ 3 - If a circular reference is found, we fall back to referential equality.
+ 4 - a range is written EXPR..EXPR (using the C<..> range operator, but
NOT the three-dot version C<...>, which will be treated as a boolean
operator)
- 4 - either a real number, or a string that looks like a number
+ 5 - either a real number, or a string that looks like a number
The "matching code" doesn't represent the I<real> matching code,
of course: it's just there to explain the intended meaning. Unlike
diff --git a/pp_ctl.c b/pp_ctl.c
index 0b172c55ed..1b4bbf5133 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -4091,7 +4091,9 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
HE *he;
bool andedresults = TRUE;
HV *hv = (HV*) SvRV(d);
- (void) hv_iterinit(hv);
+ I32 numkeys = hv_iterinit(hv);
+ if (numkeys == 0)
+ RETPUSHNO;
while ( (he = hv_iternext(hv)) ) {
ENTER;
SAVETMPS;
@@ -4118,6 +4120,8 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
bool andedresults = TRUE;
AV *av = (AV*) SvRV(d);
const I32 len = av_len(av);
+ if (len == -1)
+ RETPUSHNO;
for (i = 0; i <= len; ++i) {
SV * const * const svp = av_fetch(av, i, FALSE);
ENTER;
diff --git a/t/op/smartmatch.t b/t/op/smartmatch.t
index c480e0e14d..5fd35870b9 100644
--- a/t/op/smartmatch.t
+++ b/t/op/smartmatch.t
@@ -212,8 +212,8 @@ __DATA__
! [1] \&foo
! {a=>1} \&foo
# empty stuff matches, because the sub is never called:
- [] \&foo
- {} \&foo
+! [] \&foo
+! {} \&foo
! qr// \&foo
! undef \&foo
undef \&bar
@@ -224,8 +224,8 @@ __DATA__
@ "foo" \&fatal
@ qr// \&fatal
# sub is not called on empty hashes / arrays
- [] \&fatal
- +{} \&fatal
+! [] \&fatal
+! +{} \&fatal
# - null-prototyped subs
! undef \&FALSE