SPUG: Unidentified Flying Objects

Yitzchak Scott-Thoennes sthoenna at efn.org
Wed Jan 11 01:38:47 PST 2006


On Tue, Jan 10, 2006 at 10:26:20AM -0800, Fred Morris wrote:
> sub zap {
> 
>     my $self = shift;
>     my $new_me = shift;
> 
>     print "ZAP!\n";
> 
>     return bless $self, $new_me;
> 
> } # &zap

This is better written

sub zap {
  my $new_me = $_[1];

  print "ZAP!\n";

  return bless $_[0], $new_me;
}

otherwise the overloaded flag won't be correctly set on the zapped
object if zapping from an overloaded class to a non-overloaded class
or vice versa.

Even done this way, copies of the object/reference will be out of
sync:

$ perl
use warnings;
use strict;
{
  package Foo;
  use overload q!""! => sub { "overloaded!" };
  sub new { bless {} }
}
{
  package Bar;
  sub new { bless {} }
}
sub zap { bless $_[0], $_[1] }
$a = $b = Foo::->new;
zap($b, "Bar");
print "a: ", eval{"$a"} || "stringify croaked!", " b: $b\n";

$a = $b = Bar::->new;
zap($b, "Foo");
print "a: ", eval{"$a"} || "stringify croaked!", " b: $b\n";
__END__
a: stringify croaked! b: Bar=HASH(0x47f060)
a: Foo=HASH(0x4b89a0) b: overloaded!


This happens because the overload flag is stored on the reference, not
the referent, for efficiency, so only the copy of the reference passed
to bless and any later copies of it are correctly overloaded.


More information about the spug-list mailing list