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

In one project, I AUTOLOAD every method and sub routine from a data base: I wrote a UNIVERSAL::AUTOLOAD routine that loads the code, initializes the packages and inheritance trees when a package is first used.

However, I have a small problem: When I call a normal sub routine (not a method) and have the -w switch on, I get a warning:
Use of inherited AUTOLOAD for non-method PKG::foo is depreciated at (eval 412) line 42.
I would like to switch this warning off but leave all other warnings on. Is there a good way to do it?

At the moment, I hacked the perl source: I found the line where the error message is generated. There I added code to check the variable $CB::NoWarning. If it is false, the warning will be issued as usual. If it is true, the warning is suppressed.

It works, but it doesn't look right...

Replies are listed 'Best First'.
Re: Switch off warning for UNIVERSAL::AUTOLOAD
by merlyn (Sage) on Aug 08, 2000 at 16:29 UTC
    If you're not using 5.6 (which has controllable warnings), try this:
    BEGIN { $SIG{__WARN__} = sub { warn @_ unless $_[0] =~ /inherited AUTOLOAD/; }; }
    Or stop calling autoloaded class methods for classes where you've not installed an AUTOLOAD handler.

    In other words, if A "isa" B, don't create just B::AUTOLOAD: also install A::AUTOLOAD. That's all this is complaining about... it had to follow the @ISA for a class method or an ordinary subroutine (and that's guaranteed to break in the future... hence the deprecated part of the message).

    -- Randal L. Schwartz, Perl hacker

      Thanks to you help, I finished now version 0.1 of the "EveryThing" module: After

      use EveryThing;

      Perl pretends to have loaded all routines from a data base (a hash tied to a DB_File) and to initialized all packages.

      In reality, it waits until a routine is first called and loads it then. Also, package initialisation is delayed until the package is actually used.

      Of course, the subtle details between OOP and AUTOLOADING require some attention but I believe that I got it (mostly) right. Maybe I post the module to this site when I have added some documentation and utilities...

      Now, I am scared because you write: <quote> and that's guaranteed to break in the future... </quote> This means my module will not work in the future: It relies on the fact that EveryThing will call UNIVERSAL::AUTOLOAD in case it's not yet in the system.

      In fact, an older version of the module did some guesswork what modules a piece of code might want to use and initialized AUTOLOAD for all these packages. But this guesswork required some assistance from the programmer in cases like calling a constructor of a variable class. Also, the first code piece called needed some explicit initialisation.

      I completely agree that AUTOLOADing via @ISA is not the RightThing. But UNIVERSAL::AUTOLOAD is different because it has an additional useful semantics.

      Thanks again for you quick help.

      Yaakov

      Thank you very much for your answers.

      Yaakov

RE: Switch off warning for UNIVERSAL::AUTOLOAD
by Anonymous Monk on Aug 08, 2000 at 22:05 UTC
    The quickest way is to do this: my $tmp = $^W; local($^W) = 0; #offending code here $^W = $tmp; # reset to original state Although, if you're writing it correctly you shouldn't be getting this warning. Are you writing with 'use strict;'? Erik Hollensbe
      You are completely right. I should not get a warning for correct code. Because of this, I switch the warning on and use strict.

      However, the UNIVERSAL::AUTOLOAD method provides a functionality (to catch all missing routintes in one place) that I need and that Perl has decided to drop in the future. So, while it is still there, I want to use it and Perl wants to warn me that in future the code might break. I read the warning and want to suppress it now. Still other warnings should be displayed and fixed in the code.

      As it stands, every piece of code that calls a function could trigger UNIVERSAL::AUTOLOAD and thus be "offending".

      Maybe there is a way to keep the UNIVERSAL::AUTOLOAD feature in Perl ...