Package: perl
Version: 5.14.2-14
Severity: important
Tags: patch fixed-upstream

Perl 5.14.3 included the attached patch, which fixes incorrect smartmatch
precedence.

$ perl -lwe '{ package A; use overload "~~" => sub { print "in overloaded match 
A"; }; } { package B; use overload "~~" => sub { print "in overloaded match B"; 
}; } my $a=bless({},"A"); my $b=bless({},"B"); print $a ~~ $b'   
in overloaded match A
1

According to the documented behaviour, the first line should be 
in overloaded match B

There's some background at
 http://www.nntp.perl.org/group/perl.perl5.porters/2011/07/msg174260.html
where the upstream consensus is clearly that this is a misfeature that
nobody should be counting on and works against the current documentation.

The patch removes two incorrect test cases; quoting Leon Timmermans in
the thread:

>> It fixes the issue but
>> makes two tests in t/op/smartmatch.t fail. It creates a failure if you
>> match an object with smartmatch overloading with an object that has
>> overloading but not for smartmatching (in case of the test,
>> stringification overloading). I'm not sure that case is sane to begin
>> with though.
>
> IMO, in this case following the left hand (the current behavior) is
> simply insane, for reasons Ricardo already explained. Following the
> right hand if it doesn't overload smartmatching is simply impossible:
> it can't know if it should use the code, hash, regexp, array, string
> or number overloading. Making this obscure use-case die is the only
> possible sane thing we can do. 

The issue isn't a regression from squeeze, but we think it should be
fixed rather sooner than later, on the principle of least surprise.
-- 
Niko Tyni   [email protected]
>From 011be0badf32a8d73f13b6565fbd8c398f8ab27e Mon Sep 17 00:00:00 2001
From: Leon Timmermans <[email protected]>
Date: Mon, 23 Jan 2012 02:01:00 +0100
Subject: [PATCH] Enforce Any ~~ Object smartmatch precedence

---
 pp_ctl.c          |    2 +-
 t/op/smartmatch.t |    4 +---
 2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/pp_ctl.c b/pp_ctl.c
index 60bc30d..06d9124 100644
--- a/pp_ctl.c
+++ b/pp_ctl.c
@@ -4374,7 +4374,7 @@ S_do_smartmatch(pTHX_ HV *seen_this, HV *seen_other)
 	DEBUG_M(Perl_deb(aTHX_ "    applying rule Any-Object\n"));
 	DEBUG_M(Perl_deb(aTHX_ "        attempting overload\n"));
 
-	tmpsv = amagic_call(d, e, smart_amg, 0);
+	tmpsv = amagic_call(d, e, smart_amg, AMGf_noleft);
 	if (tmpsv) {
 	    SPAGAIN;
 	    (void)POPs;
diff --git a/t/op/smartmatch.t b/t/op/smartmatch.t
index da4840e..79c9847 100644
--- a/t/op/smartmatch.t
+++ b/t/op/smartmatch.t
@@ -73,7 +73,7 @@ my %keyandmore = map { $_ => 0 } @keyandmore;
 my %fooormore = map { $_ => 0 } @fooormore;
 
 # Load and run the tests
-plan tests => 351;
+plan tests => 349;
 
 while (<DATA>) {
   SKIP: {
@@ -223,8 +223,6 @@ __DATA__
 @	"object"	$str_obj
 @	FALSE		$str_obj
 # Those will treat the $str_obj as a string because of fallback:
-!	$ov_obj		$str_obj
-	$ov_obj_2	$str_obj
 
 # object (overloaded or not) ~~ Any
 	$obj		qr/NoOverload/
-- 
1.7.10.4

Reply via email to