re.pl:变量在块内的作用域不正确



示例:

~ $ re.pl
$ { my $abc = 10 ; $abc }
10
$ $abc
10
$ 

这是有案可查的发现吗?

这似乎是Lexical::Persistence中的一个错误,Devel::REPL使用它来管理跨多个eval s持久化的词法环境。

下面是一个没有Devel::REPL的bug演示。此代码错误地生成了$abc,10的值,即使它在内部范围内。

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'};

我报告了一个针对该模块的错误,我们拭目以待!

同样值得注意的是,Matt Trout(Devel::REPL的主要作者)的新词汇持久化模块Eval::WithLexicals是否存在这个问题:

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";

按照预期生成10,然后第二个eval抛出预期的Global symbol "$abc" requires explicit package name错误。

$a$b是用于排序的特殊变量。参见perldoc -f sort

不要使用$a$b

来自Perlvar(Perl预定义变量)文档:

$a $b

使用sort()时的特殊包变量,请参阅排序。由于这种特殊性,即使使用strict 'vars'杂注,也不需要声明$a和$b(使用<strong]use vars>或our())。如果您希望能够在sort()比较块或函数中使用它们,请不要使用my $amy $b对它们进行词汇化。

如果您直接在Perl解释器中运行代码,则不会发生这种情况:

$ 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.
()

可能您在Devel::REPL中发现了一个错误。

最新更新