AUTOLOAD

Tim Sweetman ti at lemonia.org
Sun Jan 14 23:01:01 GMT 2007


Simon Cozens wrote:

> Tim Sweetman:
> 
>>Damian's "Best Practices" say: don't use AUTOLOAD.
> 
> 
> I say: Don't use Damian's "Best Practices".

OK, serious question: do you consider the whole book to be nothing but a 
big paperweight, or are you being at least slightly facetious?

> Write code that is as easy for others to read.

How about writing code which doesn't rely on strange subtleties which 
experts in the language are unable to agree on?

Example:
Damian Conway provides Class::Std, but then advises against use of 
either AUTOLOAD or AUTOMETHOD. Several people appear to disagree with 
him, though they haven't (here) said why...

chromatic says (I paraphrase) if you implement AUTOLOAD, but don't 
implement can, that's a bug, and you're lazy. (That might be a 
compliment, in this context, I'm unsure).

The UNIVERSAL perldoc says:
>            "can" cannot know whether an object will be able to provide a
>            method through AUTOLOAD, so a return value of undef does not neces-
>            sarily mean the object will not be able to handle the method call.

Hmm. Well, that's not consistent with English, in which a bird can fly, 
and a cat can't fly, and throwing an animal out the window does not 
render it able to fly because it previously didn't, but now it has. 
(This is why we have concepts like "I haven't tested it yet").

The UNIVERSAL perldoc also says:
>            "can" can be called as a class (static) method, an object method,
>            or a function.

This suggests that, at least unless told otherwise, Perl programmers 
wouldn't expect can to be overridden by a class.

It also says:
>            To get around this some module authors use a forward declaration
>            (see perlsub) for methods they will handle via AUTOLOAD

And that's "use a forward declaration". NOT blame the "stupid" 
programmer for expecting UNIVERSAL::can($thing, "fly") to do what it 
means in English; NOT use Class::Std or UNIVERSAL::can to push the 
UNIVERSAL class's can implementation out of the way and do something 
different (and hopefully better).

(OK, they agree on what happens, and how the Perl interpreter works, but 
as for what anyone's actually supposed to be doing, or what one can 
reasonably expect from a module author...?)

(Simon Cozens)
> I have no problems with people using AUTOLOAD, so
> long as AUTOLOAD checks its parameters; that way, what you're doing doesn't
> it doesn't change the interface to your class, and only exposes the things you
> document anyway.

For a start, "can" returns potentially random output for a given method. 
This is affecting the interface. (Admittedly, not doing anything the POD 
of UNIVERSAL doesn't warn you of, but still...)

Then again, AUTOLOAD is quite happy to snaffle someone else's interface 
from within the inheritance hierarchy.

How is any of this not changing the interface to your class?

And then Dirk Koopman says: "life is too short to code every accessor". 
And so it is, but you have the, mostly, perfectly serviceable
a) create all the accessors you'll need in a loop at compiletime

and

b) have accessors like ->get("colour"), rather than ->get_colour, and 
then the need for loads of accessors goes away

options. And there probably are cases where those suck, or where you 
really can't determine the set of methods/accessors in advance.

Anyway:
 > Write code that is as easy for others to read.

I agree, heartily. It's much easier to read code if you know where to 
look. AUTOLOAD, and associated exotica, cause code to suddenly appear 
when summoned. Code that moves about is harder to read.

Tim



More information about the london.pm mailing list