Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl-Sensitive Sunglasses
 
PerlMonks  

localizing __PACKAGE__?

by perl5ever (Pilgrim)
on Feb 25, 2011 at 23:48 UTC ( [id://890231]=perlquestion: print w/replies, xml ) Need Help??

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

When I create a closure, are unqualified function names permanently tied to a particular package, or is it possible to change what package they will be looked up in at the time the closure is executed?

Example:

package other; sub hello { ... } package main; sub foo { # some magic here to make hello -> other::hello? $_[0]->(); } foo(sub { hello() });
When this code is executed, the call hello() will try to call main::hello. However, is it possible to put some magic in foo so that the function call hello() will be resolved as a call to other::hello()?

Replies are listed 'Best First'.
Re: localizing __PACKAGE__?
by Corion (Patriarch) on Feb 25, 2011 at 23:56 UTC

    You can do something like the following but it's a horrible thing to do in the long run:

    package main; sub foo { local *main::hello = \&other::hello; $_[0]->(); };

    What problem are you trying to solve that you can't solve by rewriting the calling code?

Re: localizing __PACKAGE__?
by JavaFan (Canon) on Feb 26, 2011 at 12:41 UTC
    No, doing it in foo is too late, and short of actually overriding main::hello, you cannot do what you want. The code to hello() is resolved inside the anon sub, not inside foo(). Said sub is compiled inside the package main, so a call to an unqualified sub will be resolved in the package.

    You may want to do something like:

    foo(sub {package other; hello()}); # Always calls other::hello
    or
    sub foo {package other; $_[0]->()} foo(sub {no strict 'refs'; &{(caller)[0] . "::hello"}()}); # Always ca +ll hello in callers namespace.
Re: localizing __PACKAGE__?
by TomDLux (Vicar) on Feb 26, 2011 at 01:24 UTC

    The better solution would be to be clear when you invoke foo() as to which hello(0) you want it to call. If, instead of passing the anonymous sub to foo(), you were to attempt to invoke hello(), it would fail because there is no hello(). What makes you think it should work any better inside foo()?

    foo(sub { other::hello() } );

    As Occam said: Entia non sunt multiplicanda praeter necessitatem.

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (6)
As of 2025-06-12 11:53 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.