use strict; use warnings; # Comment out unless 5.6+ package Bar; use vars qw/ $AUTOLOAD /; sub new { bless {}, shift }; sub AUTOLOAD { print "AUTOLOAD: @_ : $AUTOLOAD\n"; my $self = shift; die "'$self' is not an object\n" unless ref($self); print "Doing some AUTOLOAD'ing magic\n"; } sub DESTROY {} sub frobnitz { my $foo = new Foo ( input => { } ); } package Foo; sub new { bless {}, shift }; package main; my $bar = Bar->new; $bar->frobnitz;
Go ahead ... I'll wait.
Now, cut'n'paste the 4 lines starting with package Foo; and paste them above package Bar; and re-run. See any differences? And, if you want, revert the code to its original, but change
tomy $foo = new Foo ( input => { } );
my $foo = Foo->new( input => { } );
That is why you shouldn't use the Indirect notation. (By the way, this was tested with 5.8.4 on Solaris.) The issue, by the way, is that the indirect notation is fixed at compile-time, not run-time. This can be seen as
is parsed (as shown by B::Deparse) asmy $foo = new Foo ( input => { } );
my $foo = new(Foo('input', {}));
Since the Foo() function (not method) doesn't exist in package Bar, AUTOLOAD is called. Since the author anticipated that AUTOLOAD would only be called as a method, the first parameter is assumed to be the object. Ooops.
Now, some anticipated responses:
Well, I wouldn't, but code I'm maintaining might for accessor "generation". Or, some "helpful" coworker might add it in later.
Because AUTOLOADs in the parent class(es) will also cause this problem and you may not control what classes you are inheriting from. Plus, any changes to the parent classes (such as the addition of an AUTOLOAD) will trigger this problem without any changes to your code.
It's really easy to create a situation where you cannot have a correct order. For example, if you create a frobnitz() method in Foo that mirrors the frobnitz method in Bar, plus added a copy of the AUTOLOAD in Foo. What's the correct order to use now?
Because a lot of applications will load all classes being used at startup, particularly if the application is in a persistent environment, such as mod_perl.
Plus, there are instances where you are handed a class name and expected to instantiate an object from it with the guarantee that the class has already been loaded into memory.
Being right, does not endow the right to be rude; politeness costs nothing.
Being unknowing, is not the same as being stupid.
Expressing a contrary opinion, whether to the individual or the group, is more often a sign of deeper thought than of cantankerous belligerence.
Do not mistake your goals as the only goals; your opinion as the only opinion; your confidence as correctness. Saying you know better is not the same as explaining you know better.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Why you shouldn't use the Indirect notation with AUTOLOAD
by Anonymous Monk on Feb 28, 2005 at 16:50 UTC | |
by chromatic (Archbishop) on Feb 28, 2005 at 18:47 UTC | |
by TedYoung (Deacon) on Feb 28, 2005 at 18:58 UTC | |
by dragonchild (Archbishop) on Feb 28, 2005 at 19:06 UTC | |
by Anonymous Monk on Mar 01, 2005 at 10:10 UTC | |
by Mugatu (Monk) on Feb 28, 2005 at 21:18 UTC | |
|
Re: Why you shouldn't use the Indirect notation with AUTOLOAD
by no_slogan (Deacon) on Mar 01, 2005 at 04:01 UTC |