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

My first question is simple. I was looking thru the slides for gnat's "Stages of a Perl programmer" and saw this:
sub AUTOLOAD { my $name = $AUTOLOAD; $name =~ s/^.*:://; *$name = sub { ....... }; goto &$name; }

My question is: what package will the subroutine be created in? The invoking package name or the package that AUTOLOAD is defined in?

My guess is the latter, not the former but I wanted to make sure.

Replies are listed 'Best First'.
Re: oop - obvious AUTOLOAD question
by fglock (Vicar) on Sep 25, 2002 at 18:00 UTC

    It will be defined in __PACKAGE__ - the current package.

    update: The normal behaviour would be to define the method in the current object's namespace, but you are overriding this with  s/^.*:://.

    update: see rir explanation below, then come back to this example.

    An example:

    package One; sub AUTOLOAD { my $name = $AUTOLOAD; $name =~ s/^.*:://; *$name = sub { print "called $name inside ",__PACKAGE__,"\n" }; goto &$name; } package Two; @ISA = qw(One); package Main; One->try1(); Two->try2(); $a = bless {}, Two; $a->try3();

    output:

    called try1 inside One called try2 inside One called try3 inside One called DESTROY inside One

    update: more interesting example

Re: oop - obvious AUTOLOAD question
by mirod (Canon) on Sep 25, 2002 at 18:18 UTC

    This shoudl show you: it's in the package that AUTOLOAD is defined in.

    #!/bin/perl -w use strict; my $obj= foo->new; $obj->toto(); foo::toto(); toto(); # dies an horrible death! package foo; use vars qw($AUTOLOAD); sub new { return bless {}; } sub AUTOLOAD { my $name = $AUTOLOAD; $name =~ s/^.*:://; no strict 'refs'; *$name = sub { print "in $name\n"; }; goto &$name; }
Re: oop - obvious AUTOLOAD question
by thraxil (Prior) on Sep 25, 2002 at 18:06 UTC

    AUTOLOAD is called only after the entire inheritance tree has been checked for the method. first the tree is searched in "left-most parent wins" order for the method. then the tree is searched for an AUTOLOAD in the same order.

    so if you have:

    package A; ... sub AUTOLOAD { } package B; @ISA = qw(A); ... package main; my $object = new B(); $object->method();

    it will look at B for method(), then it will look at A for method(), then it will look for an AUTOLOAD in B, then finally it will look for an AUTOLOAD in A.

    anders pearson

Re: oop - obvious AUTOLOAD question
by rir (Vicar) on Sep 25, 2002 at 18:47 UTC
    The current package, where AUTOLOAD is defined is where
    the subroutine is created.

    This is also the namespace in
    which the created routine exists. This is because you stripped
    off the explicit package name. You could specify the namespace
    if you wish. Why? Efficiency maybe. Caching the
    creations of AUTOLOAD is often a reasonable idea.
    But pushing the result back down the inheritance tree
    may not be reasonable.

    In an AUTOLOAD sub you should usually avoid handling routines
    that have a name in all uppercase. Perl has special functions
    like DESTROY, these subs are all named in all caps.

    Also isn't the goto pointless.

      The goto after AUTOLOAD is a shortcut, so that you don't have to make a new stack frame, etc, when you pass control to the new method.

      update:oops. This was a response to node 200692 but something went wrong with the links. thanks footpad

      Edited: ~Wed Sep 25 22:30:46 2002 (GMT) by footpad: Reparented, per Consideration.

        In my tests a goto &rout is slower than a plain rout.

        I don't usually care much about micro-optimizations, but
        given that AUTOLOAD is a slug, it seems a bad time to
        imply that an arcane construct is faster than a normal call.