List Info

Thread: Re: Try OO semantics before throwing fatal error




Re: Try OO semantics before throwing fatal error
user name
2007-11-06 09:38:32
On Tue, Nov 06, 2007 at 03:07:16PM +0000, Nicholas Clark
wrote:
} As this is just for the case of methods, I'm not sure what
it really gains
} over making method calls by name (which has been around,
IIRC, since 5.005),
} but it would introduce both implementation and conceptual
complexity.

It breaks method calls by names. That's the point. 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?

-- 
Josh
Re: Try OO semantics before throwing fatal error
user name
2007-11-06 10:00:48
Josh Jore wrote:
> It breaks method calls by names. That's the point. 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;

What is the justification for the above line in real code? 
This is the 
real problem, not anything to do with the rest of the
example code you gave.

This is the piece of the puzzle that *many* people tried to
get Ms. 
Walsh to understand - you can't just take references of
possibly 
undefined function names and expect everything to Just
Work(TM).  It 
isn't a bug in Perl, it is a "Carbon-base error".

John

Re: Try OO semantics before throwing fatal error
user name
2007-11-06 12:10:40
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

[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )