Clever. It just needs one more goto to handle the empty case (no overrides) gracefully:
sub localize {
my $real = pop;
no strict 'refs';
goto CALL unless @_;
AGAIN: local *{shift@_} = sub { 'changed' };
goto AGAIN if @_;
CALL: $real->();
}
Even so, it's easier to understand than the nested-subroutines solution.
I wonder if anybody out there has got something even simpler.
| [reply] [Watch: Dir/Any] [d/l] |
#! perl -slw
use strict;
$, = ' ';
sub a{ 'a' }
sub b{ 'b' }
sub c{ 'c' }
sub d{ ( a, b, c ) };
sub localize {
no strict 'refs'; no warnings 'redefine';
A: local *{ +shift } = sub{ 'changed' };
goto A if @_ > 1;
+shift->();
}
print d;
print localize qw[a b c], \&d;
print d;
print localize qw[a c], \&d;
print d;
__END__
C:\test>junk
a b c
changed changed changed
a b c
changed b changed
a b c
Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
Lingua non convalesco, consenesco et abolesco. -- Rule 1 has a caveat! -- Who broke the cabal?
"Science is about questioning the status quo. Questioning authority".
In the absence of evidence, opinion is indistinguishable from prejudice.
| [reply] [Watch: Dir/Any] [d/l] |
Simpler, or did I miss something?
The empty case:
print localize qw[], \&d;
# Not a GLOB reference at line 14.
| [reply] [Watch: Dir/Any] [d/l] |
Even so, it's easier to understand than the nested-subroutines solution.
More importantly, the stackdump is more easily understood.
I wonder if anybody out there has got something even simpler.
I would hope there's something better than that. For one thing, my version doesn't allow each function to be a closure. Though, that's easy enough to fix, I suppose.
sub localize {
my $real = pop;
no strict 'refs'; no warnings 'redefine';
goto CALL unless @_;
AGAIN: my $v = shift;
local *{$v} = do {
my $v2 = $v;
sub { "changed $v2" }
};
goto AGAIN if @_;
CALL: $real->();
}
My criteria for good software:
- Does it work?
- Can someone else come in, make a change, and be reasonably certain no bugs were introduced?
| [reply] [Watch: Dir/Any] [d/l] |