Beefy Boxes and Bandwidth Generously Provided by pair Networks DiBona
Perl Monk, Perl Meditation
 
PerlMonks  

AUTOLOAD does not scale

by rir (Vicar)
on May 26, 2004 at 20:39 UTC ( #356728=note: print w/ replies, xml ) Need Help??


in reply to OO Inheritence

It is not suitable to use AUTOLOAD in a module for general use. Two AUTOLOADs cannot coexist amicably in the same inheritance tree. Try it, one masks the other.


Comment on AUTOLOAD does not scale
Select or Download Code
Re: AUTOLOAD does not scale
by runrig (Abbot) on May 26, 2004 at 21:16 UTC
    Two AUTOLOADs cannot coexist amicably in the same inheritance tree. Try it, one masks the other.

    The OP only has one AUTOLOAD, in the base class. IMHO, this is fine, as long as all derived classes play nicely.

      Agreed, but I say playing nicely is a practice that does not scale. If you won't distribute the code there is nothing wrong with using AUTOLOAD.

      I am saying that AUTOLOAD does not scale well. Every use of AUTOLOAD in a program should be under the control of one party. If two separate authors use AUTOLOAD in the same program breakage is likely.

      Being conservative, I would be suspicious of any program with more than one AUTOLOAD. If two AUTOLOAD routines exist in a hierarchy there is a problem. (Don't forget UNIVERSAL.)

      This is a known problem. Consider:

      #!/usr/bin/perl use strict; use warnings; # I decide to use a module package Vehicle; use vars '$AUTOLOAD'; sub new { return bless {}, $_[0]; } # handle all "V*" calls sub AUTOLOAD { my ($key) = $AUTOLOAD =~/::(\w+)/; return if $key =~ /^[A-Z]+$/; die "Vehicle::AUTOLOAD can't cope as $key" unless $key =~ /^[vV]/; print "Leaving Vehicle::AUTOLOAD as $key$/"; } # with my program below package Animal; use vars '$AUTOLOAD'; sub new { return bless {}, $_[0]; } # handle all "A*" calls sub AUTOLOAD { my ($key) = $AUTOLOAD =~/::(\w+)/; return if $key =~ /^[A-Z]+$/; die "Animal::AUTOLOAD can't cope as $key" unless $key =~ /^[aA]/; print "Leaving Animal::AUTOLOAD as $key$/"; } package Horse; use vars qw/ @ISA /; @ISA = qw/ Vehicle Animal /; package main; # the two usages cannot work together, I needed to # know that Vehicle used AUTOLOAD so I could avoid it # or rewrite my code to eliminate AUTOLOAD. my $h = Horse->new; $h->Veh(); $h->Ani(); # call intercepted by Vehicle AUTOLOAD
      Be well.
Re: AUTOLOAD does not scale
by adrianh (Chancellor) on May 27, 2004 at 12:21 UTC
    Two AUTOLOADs cannot coexist amicably in the same inheritance tree. Try it, one masks the other

    While I am not a fan of AUTOLOAD it is perfectly possibly to have multiple AUTOLOADs coexisting amicably in the same inheritance tree. (using SUPER and NEXT).

      --! Bad saint, no cookie.

      Yes, it's perfectly possible to have AUTOLOADs in the same inheritance tree. You can even have them dispatch to one another. And, this would be a very obfuscated version of spaghetti programming. (Yes, spaghetti that's further obfu'ed!)

      Think for a second about how you would go about maintaining that kind of programming. I know which one I'd prefer to maintain!

      (By maintain, I mean that there was a wizard who wrote the software, N normal humans who extended it, and now I am handed the mess.)

      ------
      We are the carpenters and bricklayers of the Information Age.

      Then there are Damian modules.... *sigh* ... that's not about being less-lazy -- that's about being on some really good drugs -- you know, there is no spoon. - flyingmoose

      I shouldn't have to say this, but any code, unless otherwise stated, is untested

        NEXT or something like it will be built into Perl 6. People will start using it. And abusing it. And much obfu/spaghetti code will be written. But I'm still glad it's there in case I want it. (And I didn't know there was a NEXT for Perl 5, so thanks adrianh (for informing me of it)...and TheDamian (for writing it)!).

        And let me reiterate that the only reason I disagreed with rir in the first place was because of the complaint about having multiple AUTOLOAD's in the inheritance tree, yet the OP had only one AUTOLOAD, in the base class, and with no multiple inheritance as in rir's later example. I might say the same things about maintainability when you start using multiple inheritance, but I won't :-)

        --! Bad saint, no cookie.

        The statement that "Two AUTOLOADs cannot coexist amicably in the same inheritance tree" is factually incorrect and that's the only point that I am making.

        I rarely use AUTOLOAD since there is usually a better alternative. Yes it can be used badly to produce ghastly code. However, just like local, it can occasionally be very useful. It is perfectly possible to write very straightforward non-obfu code with AUTOLOAD.

        Talking about how to use AUTOLOAD well/badly is a good thing. Blanket statements that are factually incorrect are not (IMHO anyway. YMMV).

      it is perfectly possibly

      Remove "perfectly" from that sentence and I'll agree with you. From NEXT's documentation:

      Because it's a module, not an integral part of the interpreter, NEXT.pm has to guess where the surrounding call was found in the method look-up sequence. In the presence of diamond inheritance patterns it occasionally guesses wrong.

      It's also too slow (despite caching).

      I repeat what I've said earlier, that using AUTOLOAD may very well cause you a bigger problem than the one you tried to solve. (Re: is autoload bad style?)

      ihb

Log In?
Username:
Password:

What's my password?
Create A New User
Node Status?
node history
Node Type: note [id://356728]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this? | Other CB clients
Other Users?
Others examining the Monastery: (6)
As of 2014-04-19 03:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    April first is:







    Results (477 votes), past polls