gri6507 has asked for the wisdom of the Perl Monks concerning the following question:

Monks,

This is something that I should know, but have never run into before. My program has several handrolled modules, where some modules use others. Somehow, through incorrect use of the use call, I get a runtime error

Use of inherited AUTOLOAD for non-method MyModule::myFunc() is depreca +ted at MyModule.pm line nnn.
What am I missing about inheritance? I didn't think I used AUTOLOAD, just our @ISA = qw(Exporter DynaLoader);.

Thanks.

Replies are listed 'Best First'.
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:
    1. Search for the function my_func in MyModule. If found, call it. Else:
    2. 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:
    3. Search for the function my_func in the UNIVERSAL package. If found, call it. Else:
    4. Search for the function AUTOLOAD in MyModule. If found, call it. Else:
    5. 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:
    6. Search for the function AUTOLOAD in the UNIVERSAL package. If found, call it. Else:
    7. Produce a fatal (but trappable) error about a function not found.
    It's case 5 that's trapping this warning.

    Abigail

      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.

        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.
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.

    --
    edan (formerly known as 3dan)

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.

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';".

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...

      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

      --
      edan (formerly known as 3dan)

        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).
        This copy-paste was usefull for me