E
Eric
It seems that if you define a custom stringification subroutine within
a package that has an AUTOLOAD subroutine, the stringification
subroutine is 'forgotten' after it has been called once (my
speculation). You can bless the object again to get the
stringification to work one more time...
The following code demonstrates the effect. Sorry for the length, I
did tried to simplify it as much as possible. I am running Perl 5.8.
use strict;
use warnings;
my $model = Model->new({type => { id => 'Foo' }});
print "1: ", $model->type, "\n"; # prints Foo
print "2: ", $model->type, "\n"; # prints Model=HASH(0x804c844)
my $type = $model->type;
bless $type, 'Model';
print "3: ", $type, "\n"; # prints Foo
package Model;
use overload '""' => \&_string;
sub new
{
my ($class, $data) = @_;
return bless $data,
ref($class) || $class;
}
sub _string
{
my ($self) = @_;
return $self->id || '?';
}
sub AUTOLOAD
{
(my $field = our $AUTOLOAD) =~ s/.*:://;
no strict 'refs';
*$field = sub { my ($self) = @_; return $self->_get($field) };
goto &$field;
}
sub _get
{
my ($self, $key) = @_;
return $self->_get_scalar($self->{$key})
if exists $self->{$key};
}
sub _get_scalar
{
my ($self, $value) = @_;
$value = $self->new($value)
if (ref $value eq 'HASH');
return $value;
}
a package that has an AUTOLOAD subroutine, the stringification
subroutine is 'forgotten' after it has been called once (my
speculation). You can bless the object again to get the
stringification to work one more time...
The following code demonstrates the effect. Sorry for the length, I
did tried to simplify it as much as possible. I am running Perl 5.8.
use strict;
use warnings;
my $model = Model->new({type => { id => 'Foo' }});
print "1: ", $model->type, "\n"; # prints Foo
print "2: ", $model->type, "\n"; # prints Model=HASH(0x804c844)
my $type = $model->type;
bless $type, 'Model';
print "3: ", $type, "\n"; # prints Foo
package Model;
use overload '""' => \&_string;
sub new
{
my ($class, $data) = @_;
return bless $data,
ref($class) || $class;
}
sub _string
{
my ($self) = @_;
return $self->id || '?';
}
sub AUTOLOAD
{
(my $field = our $AUTOLOAD) =~ s/.*:://;
no strict 'refs';
*$field = sub { my ($self) = @_; return $self->_get($field) };
goto &$field;
}
sub _get
{
my ($self, $key) = @_;
return $self->_get_scalar($self->{$key})
if exists $self->{$key};
}
sub _get_scalar
{
my ($self, $value) = @_;
$value = $self->new($value)
if (ref $value eq 'HASH');
return $value;
}