AUTOLOAD

ti@lemonia.org ti at lemonia.org
Wed Jan 17 16:43:32 GMT 2007


Simon Cozens:
> Dirk Koopman:
>> Could you please specify exactly what is wrong with the above statement?
>>>When messing with AUTOLOAD, the only thing that can() and its friends
>>> can
>>>tell you, reliably, about is any static method - such as
>>>$foo->can('AUTOLOAD').
>
>> Note the use of the word "reliably", which I choose to interpret as "at
>> *all* moments during the running of a program". The fact that (what I
>> choose to call) non-static methods can be created during the running of
>> a program, either through the use of AUTOLOAD or by other means, does
>> not equate to "reliable" in the context of the above statement +
>> example.

> OK, your statement is wrong in at least three ways.

> First, there is no such thing as static and non-static methods. There are
> entries in a hash. That's all.

Pardon?

Builder: "A house is built from bricks"
Physicist: "NO!! It's built from ATOMS! There are no such things as
bricks, just the atoms they're made from!"

Evidently, the physicist is right that there are atoms in the house (or,
at least, that he concieves of a useful theoretical model, which involves
assuming that the house is made of atoms). He is wrong about the concept
"brick" is useless.

In context, it seems plain that "static" refers to functions that are
brought into existance when the module in question is compiled, and
"dynamic" refers to those which appear in response to an AUTOLOAD call.
Granted, none of this is entirely black and white, because Perl is, as you
say, a dynamic language, but it's a reasonable distinction to make.

> Second, ->can is reliable at all moments during the running of a program.
> It
> tells you what methods are available at the moment when you call it.

To paraphrase:
'When I use a word,' Simon Cozens said, in a rather scornful tone, 'it
means just what the Perl interpreter chooses it to mean, neither more nor
less.'
'The question is,' said Alice, 'whether you can make "can" and "available"
mean so many different things.'
'The question is,' said Simon, 'which is to be master - you, or the Perl
compiler. That's all.'

UNIVERSAL::can tells you what methods are *in the hash*. It doesn't tell
you what AUTOLOAD would do, because, as you say, it can't. This is because
it can't predict the future, but also because the interfaces and
conventions of Perl don't have anything to plug into AUTOLOAD which also
sorts out "can". (Well, there are things that do that, like Class::Std,
but they're not in very wide usage).

UNIVERSAL::can is an abstraction, and a somewhat leaky one in this case.
Your "There are no abstractions! Just hash tables" argument is, after all,
merely a strange pattern of polarised ferrous particles on a rotating
platter, a small collection of spinning rust.

> Perl should not be expected to reward stupidity.

Wrong.

Absolutely dead wrong, in fact.

Consider the humble domestic power point.

Consider the Victorian factory, with its rotating drive belts, and the
hazard they present to one who slips, touches them by accident, or falls
over.

One third of the power point is the earth pin, whose very purpose is to
protect you, householder, from becoming substantially injured, dead, a
human earth fault, or all three. Electrical engineers do not, as a rule,
say "We'll presume you decided to connect the metal chassis of your
washing machine to live, and act as a human conductor". Granted, both the
factory drive belts, and the live pin of the plug, have their hazards, and
nothing is entirely foolproof; nor does anything protect absolutely
against sufficiently poor luck.

One of the purposes of engineering is to make the things you're intending
to do easier, and other things harder (Apple's magsafe connectors: easy to
unplug, hard to knock your laptop onto the floor). This has the effect of
rewarding stupidity, or, at least, punishing it less harshly.

This is a good thing.

This is why we're not all trying to write machine code.

> [...]
> Entries in a hash table do not appear by
> magic. They're put there either at compile time or at run time. They're
> put
> there by code. Your code. You should know what your code does.

The point is: being able to attach components to each other, and have
reasonable confidence in, if not things working, then at least things
behaving consistently, and, if not thing behave consistently, at least
nobody dying as a result.

(you're not using AUTOLOAD and UNIVERSAL::can for nuclear reactor
controls? right, good...)

If you were to say UNIVERSAL::can($obj, "foo"), or, indeed,
$obj->can("foo"), where foo is a method which AUTOLOAD loads on demand,
the answer you get depends on *whether that method's been called yet, by
anything else*.

This is class-internal state of no external consequence, and is, in a
sense, nondeterministic. (If you rewind the state of the world to where it
was last time and go again, or do something similar with your Perl
interpreter, then, yes, the results are deterministic, but that's not the
point).

(Quoting from Simon Cozens, writing, again, but later):
> can() tells you what the object can do now. This is why we call it can(),
> and not might_possibly(). If you want to implement might_possibly(), feel
> free [...]

It's called can(). A more accurate name might be
can_because_its_in_the_hash_already(); it was called can because that's
less of a mouthful, and because it mostly represents what a module can do,
because most modules don't use AUTOLOAD. (OK, I admit, there's some
guesswork there, history may disprove the details...)

>Once again this is nothing to do with AUTOLOAD. I honestly don't understand
>why you're picking on AUTOLOAD, when it sounds very much like your real
>gripe is that you're choosing to program in a dynamic language despite
>the fact that you actually don't like the flexibility that dynamic
>languages give you.

Eh?

The advantage of a dynamic, loosely defined language (and one which
doesn't enforce encapsulation of modules, and whatnot) is you can move
stuff around, create all your accessors without repeating code, and
whatnot.

Perl allows some "dynamic" stuff which nobody in their right mind would
want in production code.

The disadvantage is you may disagree with other programmers about which
bits constitute walls, and whether it's ok to suddenly move them (in this
case, use of AUTOLOAD, and whether corresponding redefinition of can and
UNIVERSAL::can is necessary, unnecessary, helpful, or unhelpful).

I don't expect for a moment to find an immediate consensus about which
"dynamic" tricks qualify as evil, though I confess I was expecting rather
fewer cries of "'dynamic' doesn't mean anything!", "'trick' is something
you do with a hat, and nothing to do with Perl!" and "There aren't any
programs anyway, just heaps of spinning rust!".

Tim




More information about the london.pm mailing list