Although it looks like a regular operator,
=
has a special and slightly subintuitive meaning
as an overload key. It does not overload the Perl
assignment operator. It can't, because that operator has to be
reserved for assigning references, or everything breaks.
The handler for =
is used in
situations where a mutator (such as ++
,
--
, or any of the assignment operators) is applied
to a reference that shares its object with another reference. The
=
handler lets you intercept the mutator and copy
the object yourself so that the copy alone is mutated. Otherwise,
you'd clobber the original.
$copy = $original; # copies only the reference ++$copy; # changes underlying shared object
Now, bear with us. Suppose that $original
is
a reference to an object. To make ++$copy
modify
only $copy
and not $original
, a
copy of $copy
is first made, and
$copy
is assigned a reference to this new object.
This operation is not performed until ++$copy
is
executed, so $copy
coincides with
$original
before the increment—but not afterward.
In other words, it's the ++
that recognizes the
need for the copy and calls out to your copy constructor.
The need for copying is recognized only by mutators such as
++
or +=
, or by
nomethod
, which is described later. If the
operation is autogenerated via +
, as in:
$copy = $original; $copy = $copy + 1;
then no copying occurs, because +
doesn't
know it's being used as a mutator.
If the copy constructor is required during the execution of some
mutator, but a handler for =
was not specified, it
can be autogenerated as a string copy provided the object is a plain
scalar and not something fancier.
For example, the code actually executed for the sequence:
$copy = $original; … ++$copy;
might end up as something like this:
$copy = $original; … $copy = $copy->clone(undef, ""); $copy->incr(undef, "");
This assumes $original
points
to an overloaded object, ++
was overloaded with
&incr
, and =
was overloaded
with &clone
.
Similar behavior is triggered by $copy =
$original++
, which is interpreted as $copy =
$original; ++$original
.