faiz has asked for the wisdom of the Perl Monks concerning the following question:
I have just encountered the following strangeness:
A subroutine appears to 'remember' a
my variable
from it's previous invocation:
# A 'wannabe' foreach, which: # - takes a CODE ref as an optional first argument # - applies it to the rest of the args # - If no CODE ref was passed, then it uses a closure of its # own that simply shoves all the args into an accumulator list # which it just dumps to STDERR sub wannabe_foreach { my $func = shift if ref $_[0] eq 'CODE'; # optional code-ref # Funkiness: $func has a value if: # (a) the user gave it one; # (User thinks closures are funky) # (b) it mysteriously has a value. # (many people would call that 'funky') warn "my func is funky!\n" if $func; my @list = @_; my @accumulator = (); $func = sub { push @accumulator, shift } unless $func; $func->($_) for @list; warn join ",", @accumulator if @accumulator; } wannabe_foreach(1..3); # Works. Warns: '1,2,3 at foo.pl line ...' wannabe_foreach(1..4); # Gets funky. # Still funky, but at least the passed code ref is invoked. # wannabe_foreach(sub { print shift }, 1..7); print "\n"; # Plain funky again. # wannabe_foreach(1..7);
A cursory debugging shows that the line
Gets funny - $func retains a reference to the closure created in the previous invocation. Looks like the compiler is too eager to optimize the closure instances?my $func = shift if ref $_[0] eq 'CODE'; # optional code-ref
Well whatever the reason is, the fix was simply:
#my $func = shift if ref $_[0] eq 'CODE'; my $func = ref $_[0] eq 'CODE' ? shift() : undef;
So - I suspect some glaring 'overlooking the obvious' mistake on my part, but not having found a reason that I understand yet, I thought I'd ask you all.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Unforgettable Closures?
by FunkyMonk (Bishop) on Dec 09, 2007 at 11:36 UTC | |
by syphilis (Archbishop) on Dec 09, 2007 at 12:42 UTC | |
by FunkyMonk (Bishop) on Dec 09, 2007 at 14:29 UTC | |
by faiz (Acolyte) on Dec 10, 2007 at 00:55 UTC | |
by tye (Sage) on Dec 10, 2007 at 03:46 UTC | |
by faiz (Acolyte) on Dec 10, 2007 at 04:58 UTC | |
by ikegami (Patriarch) on Dec 10, 2007 at 05:59 UTC | |
| |
by tye (Sage) on Dec 10, 2007 at 05:52 UTC | |
|
Re: Unforgettable Closures?
by webfiend (Vicar) on Dec 10, 2007 at 18:46 UTC |