Padre is using Actions for menu options, shortcuts, etc. The Action for showing the Perl help search (F2) is handled by the following piece of source:
Once I verified that each F2 keypress reached this point by adding a debug print above the loop, the following debug prints got surprising results:for ( @{ $self->{event} } ) { next if ref($_) ne 'CODE'; &{$_}(@args); }
This may trigger a "Use of uninitlized value" warning as "use warnings;" is active, but I don't care of them for debug prints which never reach the public. Anyway, here is the result:print "---START---\n"; for ( @{ $self->{event} } ) { print STDERR $self->{name}." => $_\n"; next if ref($_) ne 'CODE'; &{$_}(@args); }
We're walking through an array which isn't - believe me - touched anywhere, but the first value magically changes. Memory corruption? Human computer? Moon phase problems? No! It's the $_'s evil side. The fix was simple:---START--- help.search => CODE(0x9bcb9b0) help.search => CODE(0xa2f8618) ---START--- help.search => -f help.search => CODE(0xa2f8618)
Here we go:print "---START---\n"; for my $item ( @{ $self->{event} } ) { print STDERR $self->{name}." => $item\n"; next if ref($item) ne 'CODE'; &{$item}(@args); }
What happend?---START--- help.search => CODE(0x9bcb9b0) help.search => CODE(0xa2f8618) ---START--- help.search => CODE(0x9bcb9b0) help.search => CODE(0xa2f8618)
$_ was used by the loop, but it was no copy of the first array item, it was referencing it. Because something in the called CODE(0x9bcb9b0) was using $_, the new value was stored into the referenced place - the first array item overriding it's own CODE-reference.
By using a private (my) variable for the loop, $_ isn't used any longer and the problem was gone: http://padre.perlide.org/trac/changeset/8727/trunk/Padre/lib/Padre/Action.pm
This is a common problem which triggers Perl newbies and experts and which is usually hard to find, because the errors occurs at a place somewhere later when using the modified data, but if you respect this rule, you should be safe:
Use a private my-variable for looping whenever you call a sub or method within your loop!
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: Magical data modification using $_
by ikegami (Patriarch) on Oct 11, 2009 at 17:22 UTC | |
|
Re: Magical data modification using $_
by jakobi (Pilgrim) on Oct 11, 2009 at 17:58 UTC | |
|
Re: Magical data modification using $_
by Anonymous Monk on Oct 11, 2009 at 16:52 UTC |