|
Posted by Ben Morrow on April 18, 2008, 1:59 pm
Please log in for more thread options
>
> The following short module illustrates a puzzling bug:
>
> use strict;
> package Foo;
> my $x = +{ 1 => 'one' };
>
> sub foo {
> keys %$x if 0; # should do nothing
> my $y = eval '$x'; die if $@;
> printf "%d\n", scalar keys %$y;
> }
>
> 1;
> __END__
>
>
> OK, now: the following one-liner produces the expected output:
>
> % perl -MFoo -e 'Foo::foo()'
> 1
>
> ...but if one comments-out the first line of Foo::foo, the output changes:
>
> % perl -MFoo -e 'Foo::foo()'
> 0
This can be reduced to
package Foo;
my $x = 1;
sub foo {
#$x;
my $y = eval '$x';
printf "from %s: %s\n",
scalar caller, defined $y ? $y : '<undef>';
}
foo;
1;
which gives
~% perl -MFoo -eFoo::foo
from Foo: 1
from main: <undef>
with all perls I have to hand (5.6, 5.8, 5.10, blead). This is a
longstanding bug in eval STRING: it won't capture variables from an
outer lexical scope unless they are explicitly mentioned in the
immediately surrounding scope. Any mention, such as the line commented
out, is sufficient.
What I don't understand is 1. why it works when called from the same
file and 2. I though this had been fixed in 5.10. I guess not...
> Also, is there a better solution to this problem than including
> silly "voodoo code" like the first line in Foo::foo?
Fix perl's eval-handling to work properly? :)
Ben
|