Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Autoloading and anonymous subs

by haoess (Curate)
on Jun 27, 2007 at 16:33 UTC ( [id://623666]=perlquestion: print w/replies, xml ) Need Help??

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

perlsub says:

if an "AUTOLOAD" subroutine is defined in the package or packages used to locate the original subroutine, then that "AUTOLOAD" subroutine is called with the arguments that would have been passed to the original subroutine.
package Foo; sub AUTOLOAD { __PACKAGE__ } package main; sub AUTOLOAD { __PACKAGE__ } # should print Foo print $Foo::foo->(); # main print Foo::foo(); # Foo

Does $Foo::foo->() not mean locate the sub in the package Foo?

-- Frank

Replies are listed 'Best First'.
Re: Autoloading and anonymous subs
by Joost (Canon) on Jun 27, 2007 at 18:06 UTC
    $Foo::foo->() calls the subroutine reference in $Foo::foo. (i.e, $foo in the Foo package). Assuming $Foo::foo is undefined and you're not running under strict, that would probably refer to the subroutine "" in the calling package (I'm guessing here, since I tend not to run strict-less)

    If you want to call Foo::foo() as a class method of Foo, do:

    Foo->foo();
      sub AUTOLOAD {"AUTOLOAD"} *{""} = sub {"empty"}; print $nosuch->();
      confirms your suspicion.
Re: Autoloading and anonymous subs
by shmem (Chancellor) on Jun 27, 2007 at 16:53 UTC
    Does $Foo::foo->() not mean locate the sub in the package Foo?

    No. $Foo::foo is a symbol living in the symbol table Foo, that's granted; but its contents must not neccessarily refer to package Foo. So the normal method lookup rules apply. Which means that AUTOLOAD in the package main is found first.

    update: If the content of $Foo::foo is a sub reference in the Foo namespace, the Foo AUTOLOAD is found, eg

    $Foo::foo = \&Foo::bar; print $Foo::foo->(); # Foo

    --shmem

    _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                  /\_¯/(q    /
    ----------------------------  \__(m.====·.(_("always off the crowd"))."·
    ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

      And it's always the main package:

      package Foo; sub AUTOLOAD { __PACKAGE__ } print $foo->(); package main; sub AUTOLOAD { __PACKAGE__ } __END__ main

      I just can't find the documentation for this behaviour.

      -- Frank

        You are calling an undefined coderef. This coderef (which isn't, being just nothing, or not existing) has no association with any package, albeit the variable holding "that nothingness" (if nothing can be something) has. Now, how should perl resolve that sensibly? There's no package, there's no code, there's no sub. Hence the default package (main), and as last resort, AUTOLOAD.

        The documentation is implicit in perlsub, perlref, ...

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}
      How do you take the address of a sub that needs to be AUTOLOADed before it is AUTOLOADed? Hmmm?

      Be well,
      rir

        *shrug* I just do. It's a magic called autovivification :-P
        You can take a reference to a sub that doesn't exist. It's much like forward declarations of subs:
        package Foo; sub bar; # we'll define that later \&bar; # same effect

        In fact, that's how AutoLoader works - it loads a modules autosplit.ix file which contain forward declarations of subs to be loaded. The CODE slot of the typeglob is allocated, but it's empty. That's why calling such a sub AutoLoader's AUTOLOAD is called, which requires the sub's source file on the fly.

        --shmem

        _($_=" "x(1<<5)."?\n".q·/)Oo.  G°\        /
                                      /\_¯/(q    /
        ----------------------------  \__(m.====·.(_("always off the crowd"))."·
        ");sub _{s./.($e="'Itrs `mnsgdq Gdbj O`qkdq")=~y/"-y/#-z/;$e.e && print}

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://623666]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others scrutinizing the Monastery: (4)
As of 2024-04-20 00:05 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found