summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRafael Garcia-Suarez <rgs@consttype.org>2012-03-20 09:17:02 +0100
committerRafael Garcia-Suarez <rgs@consttype.org>2012-03-20 09:31:43 +0100
commit809f751e6a79849f8fa71568def987da0addbe27 (patch)
treeb23d441a9e6f663146117f130b37e54a5ca31865
parentb5bf278af31bbe7f859e02da0ad3793feb6a55e8 (diff)
downloadperl-rgs/overload.tar.gz
Lookup overloaded assignment operators when trying to swap the argumentsrgs/overload
This is in the case where we search for an overloaded operator when passing the AMGf_assign flag (we're executing an assignment operator like +=). At the very beginning of Perl_amagic_call, if the flag AMGf_noleft is not passed, we first try to look up the overload method corresponding to the assignment operator, then the normal one if fallback is authorized. However, if this fails, when trying later to find overload magic with the arguments swapped (if AMGf_noright is not passed), this procedure was not used and we looked up directly the base operation from which the assignment operator might be derived. As a consequence of what an operator like += might have looked autogenerated even when fallback=>0 was passed. This change only necessitates a minor adjustment in lib/overload.t, where an overloaded += method wasn't corresponding semantically to the overloaded + method of the same class, which can be seen as a pathological case.
-rw-r--r--gv.c13
-rw-r--r--lib/overload.t2
2 files changed, 11 insertions, 4 deletions
diff --git a/gv.c b/gv.c
index a61c34f219..8bc7d9945d 100644
--- a/gv.c
+++ b/gv.c
@@ -2756,9 +2756,16 @@ Perl_amagic_call(pTHX_ SV *left, SV *right, int method, int flags)
&& (cvp = (AMT_AMAGIC((AMT*)mg->mg_ptr)
? (amtp = (AMT*)mg->mg_ptr)->table
: NULL))
- && (cv = cvp[off=method])) { /* Method for right
- * argument found */
- lr=1;
+ && ((cv = cvp[off=method+assignshift])
+ || (assign && amtp->fallback > AMGfallNEVER && /* fallback to
+ * usual method */
+ (
+#ifdef DEBUGGING
+ fl = 1,
+#endif
+ cv = cvp[off=method])))) { /* Method for right
+ * argument found */
+ lr=1;
} else if (((cvp && amtp->fallback > AMGfallNEVER)
|| (ocvp && oamtp->fallback > AMGfallNEVER))
&& !(flags & AMGf_unary)) {
diff --git a/lib/overload.t b/lib/overload.t
index c0478eef7f..015497b98f 100644
--- a/lib/overload.t
+++ b/lib/overload.t
@@ -202,7 +202,7 @@ is($b, "89");
is(ref $a, "Oscalar");
is($copies, 1);
-eval q[package Oscalar; use overload ('+=' => sub {$ {$_[0]} += 3*$_[1];
+eval q[package Oscalar; use overload ('+=' => sub {$ {$_[0]} += 3*"$_[1]";
$_[0] } ) ];
$c=new Oscalar; # Cause rehash