[Templates] Catching missing object methods

Tom Insam tom@jerakeen.org
Fri, 10 Feb 2006 10:57:49 +0000


> gv_fetchmethod_autoload() fetches a regular method or the AUTOLOAD method,
> so this error checking code is run either way.  We do it different in 
> Perl because the can() method doesn't account for AUTOLOAD, if memory 
> serves.

Personally, I feel that this is a bug in the module implementing 
AUTOLOAD - it should override can and return the right thing. But meh.

> So I'm not confused (at least I don't think I am :-).  Your patch makes
> perfect sense to me, and as far as I can tell it should fix the problem.

My point is that in the XS stash, we get a method object that we know 
exists (although it might be an AUTOLOAD), and call it, checking the 
error response for the perl 'that method didn't exist' error string. 
Normally, that simply can't happen - we already know, having got here, 
that the method exists. The (old) code was called if anything in the 
method ever threw a 'method doesn't exist' error, and this is fixed, but 
we could fix _that_ bug by just not looking - all errors are real errors 
at that point. This is why there was the sv_reftype bug - it really 
doesn't matter what my errormatch string contained, as long as it 
didnm't match.

The case where we _do_ need this code is where I want to implement an 
AUTOLOAD that will pretend to only implement some methods. Something like

package Blubber;

sub AUTOLOAD {
   my $self = shift;
   my ($method) = $AUTOLOAD =~ /([^:]+)$/;
   if ($method =~ /walrus) { # it's a contrived example, ok?
     return $self->{walrus_lookup}{ $method };
   } else {
     # pretend that the method didn't exist
     die "Can't locate object method \"$method\" via package 
\"".ref($self)."\"";
   }
}

(warning - may contain errors. My brain isn't a good perl compiler)

So here I want to pretend that I implement methods containing the word 
walrus. If I manage die with exactly the right string here, then TT will 
let me call [% blubber.green_walrus %] as an autoloaded method, and [% 
blubber.foo %] as a hash accessor, which is what I'm after.

This is the _only_ situation that I can think of where the 
error-catching code in the XS stash should fire, and it's not tested. My 
confusion came from the fact that my broken code didn't cause any tests 
to fail, you see.

Anyway, I have the CVS repos now, so I'll give you a patch against it to 
test this situation once I see the merge go in.

tom