Subject: | can() coderef return |
Date: | Tue, 21 Sep 2010 11:27:07 +1000 |
To: | bug-Object-Lazy [...] rt.cpan.org |
From: | Kevin Ryde <user42 [...] zip.com.au> |
In Object::Lazy 0.03 it seems calling the coderef returned by can()
reaches the target method with the lazy object not the target object.
For example the program foo.pl below prints
hello called with: Object::Lazy=HASH(0x99a0110)
where I hoped for
hello called with: MyClass=HASH(0x9f08b50)
Calling the can() coderef isn't hugely common, but I think it's supposed
to be allowed, presumably to save a couple of nanoseconds not doing a
method lookup a second time. Something like Convert::Color convert_to()
seems fairly typical (other modules have more complicated uses),
if( $code = $self->can( "convert_to_$to_space" ) ) {
return $code->( $self );
}
It could be good for maximum interoperation if Object::Lazy arranged to
return a wrapper sub from can() which would dispatch to the real method
with the real object.
Perhaps something like (only tested a little bit! :-),
sub can {
my ($self, $method) = @_;
my $built_object = $build_object->($self);
my $coderef;
return (($coderef = $built_object->can($method))
&& sub {
$_[0] = $built_object;
goto $coderef;
});
}
use strict;
use warnings;
{
package MyClass;
sub new {
my ($class) = @_;
return bless { name => 'myclass' }, $class;
}
sub hello {
my ($self) = @_;
print "hello called with: $self\n";
}
}
use Object::Lazy;
my $lazy = Object::Lazy->new (sub{
return MyClass->new();
});
my $coderef = $lazy->can('hello');
$coderef->($lazy);