re.pl: Variable not properly scoped inside block
Example:
~ $ re.pl
$ { my $abc = 10 ; $abc }
10
$ $abc
10
$
Is this a documented gotch开发者_如何学运维a?
This appears to be a bug in Lexical::Persistence, which Devel::REPL uses to manage the lexical environment persisting across multiple eval
s.
Here's a demonstration of the bug without Devel::REPL. This code incorrectly produces the value of $abc
, 10, even though it's in an inner scope.
use strict;
use warnings;
use Lexical::Persistence;
my $environment = Lexical::Persistence->new;
$environment->call(sub {
my $foo = shift;
{ my $abc = 10 };
return $foo;
});
print $environment->get_context('_')->{'$abc'};
I've reported a bug against the module, we'll see what happens!
It's also worth noting that Matt Trout (the primary author of Devel::REPL)'s new lexical persistence module, Eval::WithLexicals does not suffer from this problem:
use strict;
use warnings;
use Eval::WithLexicals;
my $environment = Eval::WithLexicals->new;
print $environment->eval('{ my $abc = 10 ; $abc }'), "\n";
print $environment->eval('$abc'), "\n";
produces 10
as expected, then the second eval throws the expected Global symbol "$abc" requires explicit package name
error.
$a
and $b
are special variables used for sorting. see perldoc -f sort
.
Don't use $a
or $b
.
From Perlvar (Perl predefined variables) documentation:
$a $b
Special package variables when using
sort()
, see sort. Because of this specialness $a and $b don't need to be declared (usinguse vars
, orour()
) even when using thestrict 'vars'
pragma. Don't lexicalize them withmy $a
ormy $b
if you want to be able to use them in thesort()
comparison block or function.
It doesn't happen if you run your code directly in the Perl interpreter:
$ perl -we '{ my $abc = 10 ; print "($abc)\n"; }; print "($abc)\n";'
Name "main::abc" used only once: possible typo at -e line 1.
(10)
Use of uninitialized value $abc in concatenation (.) or string at -e line 1.
()
May be you have found a bug in Devel::REPL.
精彩评论