On Tuesday 06 November 2007 07:38:32 Josh Jore wrote:
> If I ask ->can()
> and get a function back, I don't ever check that the
function is
> defined. Mostly I assume it's defined. It never would
have occurred to
> me that ->can and ->foo would find these ghostie
little methods.
> &foo;
> say main->can( 'foo' ); # finds CODE=(0x...)
> say defined &{ main->can( 'foo' ) }; # false
> eval 'sub UNIVERSAL::foo { }';
> main->foo; # throws error
>
> Did you just say that main->foo should work?
If I recall correctly, the stubs work the way they do so
that code like this
will work:
use Test::More tests => 2;
use Test::Exception;
package Stubs;
BEGIN { my $stub = &foo }
package main;
my $foo = Stubs->can( 'foo' );
throws_ok { $foo->() } qr/Undefined sub/, 'Stub not
callable';
{
no strict 'refs';
*{ 'Stubs::foo' } = sub
}
is( $foo->(), 2, 'stub callable after definition' );
... not that I expect that anyone ever gets can() correct,
but that's a
different rant.
If you want a more methody system, throw into Stubs:
sub new { bless {}, shift }
... and then add:
my $s = Stubs->new();
is( $s->$foo(), 2, 'stub callable as method after
definition' );
I don't think the bug is in method resolution. I don't
think the bug is in
can(). I also don't think there's a good general heuristic
that can support
this behavior while distinguishing between accidentally
taking a reference to
an undefined invokable symbol that just happens to share a
name with a method
somewhere in a resolution hierarchy, so I don't think
there's a fix for this
behavior if it happens not to be a bug in the invokable
object.
If there *is* such a heuristic though, maybe it's worth
considering Linda's
feature request.
-- c
|