in reply to how to declare a local *subname=sub{}?
Hi perl-diddler,
Although LanX has already explained several things in various posts, one keyword that has not been named in this thread is dynamic scope, personally I find this easiest to remember. local only affects things in the current dynamic scope - as explained in Temporary Values via local(), it changes the value of a global at runtime, which will also affect any functions called at runtime in the scope where local is in effect, but at the end of the scope, the previous value of the variable is restored. An example:
our $foo = "foo"; { local $foo = "bar"; sub quz { print "\$foo = $foo\n"; } } quz(); # prints "$foo = foo"
Once you realize what local is doing, you'll see that the above code is basically equivalent to this:
our $foo = "foo"; { $foo = "bar"; sub quz { print "\$foo = $foo\n"; } $foo = "foo"; } quz(); # prints "$foo = foo"
Note how quz is called after after the original value of $foo is restored. So I hope that explains why your local *asub = sub ... would cease to have any effect once Perl has completed executing your block { package Do::Stuff; ... }.
Your use of *bsub warrants some closer inspection though. In your code example, if you call $p->stuff after $p->do_internal_sub, suddenly the call the bsub works! It's a bit complicated, but if you keep in mind the distinction as to when which line is executed, it makes sense. I'll explain using this example:
#!/usr/bin/env perl use warnings; use strict; sub foo { print "orig foo\n" } sub bar { print "orig bar\n" } { local *foo = sub { print "local foo\n"; }; local *bar; sub quz { foo(); eval { bar(); 1 } or warn "calling bar failed: $@"; } sub baz { *bar = sub { print "local bar\n"; }; } quz(); # first call to quz baz(); # first call to baz quz(); # second call to quz } quz(); # third call to quz baz(); # second call to baz quz(); # fourth call to quz __END__ Subroutine main::foo redefined at local_ex.pl line 8. local foo calling bar failed: Undefined subroutine &main::bar called at local_ex +.pl line 12. local foo local bar orig foo orig bar Subroutine main::bar redefined at local_ex.pl line 15. orig foo local bar
Having said all that, I think local *foo = sub {} is one of those things that should only be used very rarely (one of those "use only if you know what you're doing and why" things). Aside from the plain wackyness of the above example code, one of the main arguments is that, as always, fiddling with global definitions can cause unintended consequences in other places in the code: if you redefine foo and then call another function, who's to say whether someone down the call tree is depending on the original definition of foo?
The two much better and "more modern" solutions IMO are simply passing around references to (anonymous) subs, or an OO design with classes where methods can be overridden in subclasses; based on what you've written, I suspect the latter might be appropriate in your case, but you'd have to explain a bit more the bigger picture of what you're trying to do.
Update: Yet another reason not to use local *bar; - it localizes everything named bar! Example in readmore tags:
our $bar = "BBB"; sub foo { print "orig foo (bar=$bar)\n" } sub bar { print "orig bar (bar=$bar)\n" } { local *foo = sub { print "local foo (bar=$bar)\n"; }; local *bar; # this also clears $bar! sub quz { foo(); eval { bar(); 1 } or warn "calling bar failed: $@"; } sub baz { *bar = sub { print "local bar (bar=$bar)\n"; }; } quz(); # first call to quz (OOPS, $bar is undef!) baz(); # first call to baz quz(); # second call to quz (OOPS, $bar is still undef!) }
(This behavior does not happen with to the local *foo = sub { ... }; form.)
A few more notes on your code:
Hope this helps,
-- Hauke D
Updated wordings in a few places.
|
|---|