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

I am writing a Perl package that has an AUTOLOAD subroutine. I use strict in my package. In the AUTOLOAD subroutine I use $AUTOLOAD which according to Perl documentation is supposed to contain the name of the subroutine that Pelr couldn't find. Here is the source code:

sub AUTOLOAD { my $subroutine_name;<BR> $subroutine_name = $AUTOLOAD; }

According to Perl documentation, the mehod AUTOLOAD will automatically get called by Perl any time a method is invoked within the given package that Perl can not find. You can then use the AUTOLOAD method to find or define the given method. Alternatively in AUTOLOAD you could just report the problem, ignore it and keep going or trigger a die. The documentation indicates that $AUTOLOAD is a global variable in which Perl will place the fully qualified subroutine name that it can not find.

The problem I am having is that the code will not compile. It states that "Global symbol "$AUTOLOAD" requires explicit package name". Do I need to put the following at the start of my Perl script?

use vars qw ( $AUTOLOAD );

Or is $AUTOLOAD supposed to be an automatic global variable that Perl should already know about?

I am a little confused. when I use strict I need to also use, "use vars qw ( @ISA );" if I want to use the @ISA array to set up inheritance, however, the list @INC and @ARGV are global variables that Perl already knows about and thus I do not need to use "use vars qw( @INC @ARGV);".

Any one know which special global variables Perl already knows about and which ones need to be explicitly stated using the "use vars qw ( ... ); " construct when the strict package is used?

I find it confusing that some special global variables require explicit declarations using "use vars qw ( ... ); " while others don't.

Any one have any useful input/feedback?

Replies are listed 'Best First'.
Re: Use of $AUTOLOAD and strict
by ikegami (Patriarch) on May 11, 2005 at 21:45 UTC

    Yes, use vars qw ( $AUTOLOAD ); would do the trick. Better yet, so would the following:

    sub AUTOLOAD { our $AUTOLOAD; my $subroutine_name = $AUTOLOAD; ... }

    The ones that need to be declared are the ones not listed by the following:

    perl -e "$,=$\=$/; print keys %::"

      That's wrong. The ones that have to be declared are the ones not in perlvar. For example, $^W does not have to be declared, but perl -e "$,=$\=$/; print keys %::" does not print it.

      Update: the exact rule is in perlvar:

      Perl identifiers that begin with digits, control characters, or punctuation characters are exempt from the effects of the "package" declaration and are always forced to be in package "main"; they are also exempt from "strict 'vars'" errors. A few other names are also exempt in these ways: ENV STDIN INC STDOUT ARGV STDERR ARGVOUT _ SIG
        The docs you quoted support me. perlvar and some variables outsides of perlvar don't need to be declared. My snippet lists all the variables in perlvar AND the variables not listed in perlvar that it acknowledges. I did mean to mention the non-text variables from perlvar (e.g. $^W) don't need to be declared either.
Re: Use of $AUTOLOAD and strict
by shemp (Deacon) on May 11, 2005 at 22:26 UTC
    2 comments. You can get around:
    use vars qw(@ISA);
    by using
    use base

    Also, a couple other variables that strict will not complain about not being explicitly declared are:
    $a & $b
    See the documentation for sort, etc.
Re: Use of $AUTOLOAD and strict
by Tanktalus (Canon) on May 11, 2005 at 21:45 UTC

    Variables that start out populated, such as @INC, will exist in order to be populated. Variables that start out unpopulated, such as @ISA or $AUTOLOAD, won't.

    That doesn't make it intuitive, although I do believe it's mostly consistant.

    Update: Added the italicised word above as per ryantate's comment below.

      What about @_, $_, $a, $b, @ARGV? They are *sometimes* populated, but then so is $AUTOLOAD.

        From strongest to weakest points:

        @ARGV is always populated - it's the arguments you've been passed. If you don't have any arguments, the list is empty - which is precisely populated with what is passed in. @INC could similarly be empty, but I'm sure it would still be created. (Of course you'd have serious other problems if @INC were empty, but we won't go there.) More realistically, %ENV could be empty, but it would still be created because it would be populated - by nothing, but populated nonetheless. Think of code like this:

        no strict; @ARGV = (); use strict; print scalar @ARGV;
        This wouldn't trigger the error - think of the first two lines as what perl does in the case of no arguments, and the latter two as representative of doing something with that nothing.

        @_ is populated - and localised - for each function call. The perl runtime has to create this to populate it. You don't create it - perl does.

        $_ is created with @_ by actually creating *_. But that's just a nit.

        $a and $b are wierd exceptions. I can't explain those. Sorry.

        Note also that these are variables that are created at compile time, not runtime. $AUTOLOAD, besides being local to each package that it deals with, is created at runtime.

Re: Use of $AUTOLOAD and strict
by rinceWind (Monsignor) on May 12, 2005 at 12:48 UTC

    I think that it is really a question of context. The built in variables that ambrus lists from perlvar are independent of which package namespace you are in. This is not the case with $AUTOLOAD. Conceivably there could be different $AUTOLOAD subs nested, and in different namespaces if one AUTOLOAD sub causes another one to be called (if it calls a non-existent sub elsewhere). Similarly, @ISA lives in package namespace and needs declaring with use vars or our.

    Specifically, the $Foo::Bar::AUTOLOAD symbol table entry does not exist except when AUTOLOAD has been invoked (but &Foo::Bar::AUTOLOAD is the subroutine). The scalar is set up with an implicit local declaration, hence the entry is removed when you return out of the call frame.

    In theory you could have nested calls to the same AUTOLOAD if the sub is itself invoking non-existent subs in the same namespace. But this is a very bizarre way of doing things.


    Something the OP did not mention is that code to autogenerate the subroutine usually needs to turn off strict 'refs' in order to put the new sub into package name space. For example: (warning: untested)

    package Foo::Bar; use strict; use vars qw/$AUTOLOAD/; sub AUTOLOAD { my ($self) = @_; #Don't use shift as we need to preserve @_ my ($meth) = $AUTOLOAD =~ /(\w+)$/; # Simple example: getter and setter for hash members # Note that the eval is here to stop the sub becoming a closure on + $meth my $acc = eval qq( sub { my \$self = shift; \@_ ? \$self->{$meth}=shift : \$self->{$meth}; } ); { no strict 'refs'; *$AUTOLOAD = $acc; } goto $acc; }

    --
    I'm Not Just Another Perl Hacker