Re: AUTOLOAD inheritance
by Abigail-II (Bishop) on Feb 12, 2004 at 14:55 UTC
|
Dynaloader uses AUTOLOAD. Since you have said that MyModule
is a Dynaloader, it means that if you call a function in the
MyModule class, and it can't be found, Perl is going to search
the Dynaloader package as well. Now, Perl also has the rule
that if a function isn't found in a package, Perl will search
for an AUTOLOAD function instead. These behaviours are not
mutally excluded. Basically what happens if you call a function my_func in the package MyModule is:
- Search for the function my_func in MyModule.
If found, call it. Else:
- Search for the function my_func in any of the
packages inherited by MyModule. This is done in a depth-first order. If a function is found, call it.
Else:
- Search for the function my_func in the
UNIVERSAL package. If found, call it. Else:
- Search for the function AUTOLOAD in MyModule.
If found, call it. Else:
- Search for the function AUTOLOAD in any of the
packages inherited by MyModule. This is done in a depth-first order. If an AUTOLOAD function is found,
call it. Else:
- Search for the function AUTOLOAD in the
UNIVERSAL package. If found, call it. Else:
- Produce a fatal (but trappable) error about a function
not found.
It's case 5 that's trapping this warning.
Abigail | [reply] |
|
|
That describes a method call (whether class or instance), but not a non-method function call. For these, steps 2 and 3 are skipped. That steps 5 and 6 happen for non-method calls is a historical oddity, and is deprecated (hence the warning).
Update: the perldiag entry for the warning tells how to eliminate it if your code was intentionally relying on the deprecated behaviour: *AUTOLOAD = \&BaseClass::AUTOLOAD; (in this case, BaseClass would be DynaLoader.) I would guess that more commonly, the warning is an indication of another problem, perhaps a missing use statement or misspelled function name.
| [reply] [d/l] |
|
|
Well, it might be helpful to tell the poster how to eliminate the warning....
Since the module in question is a Exporter and DynaLoader, and only the latter has an autoload method, adding the following to the module should work (untested in this form, slightly modified from working code in a different context):
sub AUTOLOAD
{
my $name = our $AUTOLOAD;
$name =~ s/.*:://; # lose package name
my $target = "DynaLoader::$name";
goto &$target;
}
This will get called in Abigail-II's step 4, preventing the warning from step 5. | [reply] [d/l] [select] |
Re: AUTOLOAD inheritance
by edan (Curate) on Feb 12, 2004 at 14:46 UTC
|
Here is the relevant chunk from perldiag, in case you didn't think/know to look there:
Use of inherited AUTOLOAD for non-method %s() is deprecated
(D deprecated) As an (ahem) accidental feature,
"AUTOLOAD" subroutines are looked up as methods (using
the "@ISA" hierarchy) even when the subroutines to be
autoloaded were called as plain functions (e.g.
"Foo::bar()"), not as methods (e.g. "Foo->bar()" or
"$obj->bar()").
This bug will be rectified in future by using method
lookup only for methods' "AUTOLOAD"s. However, there
is a significant base of existing code that may be
using the old behavior. So, as an interim step, Perl
currently issues an optional warning when non-methods
use inherited "AUTOLOAD"s.
The simple rule is: Inheritance will not work when
autoloading non-methods. The simple fix for old code
is: In any module that used to depend on inheriting
"AUTOLOAD" for non-methods from a base class named
"BaseClass", execute "*AUTOLOAD = \&BaseClass::AUTOLOAD"
during startup.
In code that currently says "use AutoLoader; @ISA =
qw(AutoLoader);" you should remove AutoLoader from
@ISA and change "use AutoLoader;" to "use AutoLoader
'AUTOLOAD';".
I didn't take the time/effort to read it and fully understand it, but I hope it helps nonetheless.
| [reply] |
Re: AUTOLOAD inheritance
by Tomte (Priest) on Feb 12, 2004 at 14:46 UTC
|
DynaLoader uses AUTOLOAD, so I guess the error is in code you didn't show...
tom@margo perl5 $ find . -name Dyna\*.pm
./5.8.3/i686-linux/DynaLoader.pm
tom@margo perl5 $ head -n 25 ./5.8.3/i686-linux/DynaLoader.pm | tail -
+n 15
# Tim.Bunce@ig.co.uk, August 1994
use vars qw($VERSION *AUTOLOAD);
$VERSION = '1.04'; # avoid typo warning
require AutoLoader;
*AUTOLOAD = \&AutoLoader::AUTOLOAD;
use Config;
regards,
tomte
Hlade's Law:
If you have a difficult task, give it to a lazy person --
they will find an easier way to do it.
| [reply] [d/l] |
Re: AUTOLOAD inheritance
by duff (Parson) on Feb 12, 2004 at 14:48 UTC
|
From perldiag:
- Use of inherited AUTOLOAD for non-method %s() is deprecated
-
(D deprecated) As an (ahem) accidental feature, "AUTOLOAD" subroutines are looked up as methods (using the @ISA hierarchy) even when the subroutines to be autoloaded were called as plain functions (e.g. "Foo::bar()"), not as methods (e.g. "Foo->bar()" or"$obj->bar()").
This bug will be rectified in future by using method lookup only for methods' "AUTOLOAD"s. However, there is a significant base of existing code that may be using the old behavior. So, as an interim step, Perl currently issues an optional warning when non-methods use inherited "AUTOLOAD"s.
The simple rule is: Inheritance will not work when autoloading non-methods. The simple fix for old code is: In any module that used to depend on inheriting "AUTOLOAD" for non-methods from a base class named "BaseClass", execute "*AUTOLOAD = \&BaseClass::AUTOLOAD" during startup.
In code that currently says "use AutoLoader; @ISA = qw(AutoLoader);" you should remove AutoLoader from @ISA and change "use AutoLoader;" to "use AutoLoader 'AUTOLOAD';".
| [reply] |
Re: AUTOLOAD inheritance
by bl0rf (Pilgrim) on Feb 13, 2004 at 01:09 UTC
|
Shame on you duff and edan for cutting and pasting from perldiag, without as much as an explanation.
If your'e not going to take the time to explain than don't bother cutting and pasting - just say to check out that entry in perldiag...
| [reply] |
|
|
What's wrong with cutting and pasting a relevant portion of the documentation that might help the OP? Even though I didn't explain it, I think it can still be quite helpful. Maybe I'm wrong, but I consider perldiag one of the oft-overlooked parts of the Perl documentation, therefore I don't assume someone has looked there when they post something like 'Why am I getting this error?' And why should I just post 'see perldoc perldiag' when I can just as easily snip the relevant chunk of a lengthy (3910 lines on my box) perldoc? Is PM screen real-estate so precious?
I --'ed your post
| [reply] |
|
|
You should almost always post `see perldoc perldiag` instead of cutting and pasting. You're reminding the person that they should be looking in the documentation for their answers (and here is where your current answer is).
| [reply] |
|
|
|
|
|
|
This copy-paste was usefull for me
| [reply] |