Perl 与x27之间的相互作用;出口商';使用变量';,和';本地';
我试图将这种行为归结为最简单的测试用例。考虑以下两个模块: 下午三点 下午五时 现在,下面脚本的输出-Perl 与x27之间的相互作用;出口商';使用变量';,和';本地';,perl,scope,Perl,Scope,我试图将这种行为归结为最简单的测试用例。考虑以下两个模块: 下午三点 下午五时 现在,下面脚本的输出- use strict; use warnings; use Foo; { local $Bar::BarVar = 'modified'; Foo::foo(); } Foo::foo(); 是“original”打印两次,我希望它被“modified”然后是“original”,因为我希望local声明在其整个范围内替换包变量$Bar::BarVar,包括对foo()的第一
use strict;
use warnings;
use Foo;
{
local $Bar::BarVar = 'modified';
Foo::foo();
}
Foo::foo();
是“original”打印两次,我希望它被“modified”然后是“original”,因为我希望
local
声明在其整个范围内替换包变量$Bar::BarVar
,包括对foo()
的第一次调用。怎么解释?如何在本地重写$Bar::BarVar
?您可能听我说过my
和our
创建变量(后者有别名),但local
只是临时备份值
我撒谎了
local
会进行备份,但不会备份值。它备份关联标量的地址,创建新标量,并将名称与新标量关联。在这种情况下,$Bar::BarVar
表示新标量,而$Foo::BarVar
表示旧标量
$ perl -E'
*x = \$y; say \$x, " - ", \$y;
local $y; say \$x, " - ", \$y;
'
SCALAR(0x44d7c70) - SCALAR(0x44d7c70)
SCALAR(0x44d7c70) - SCALAR(0x44ba130)
如果只备份值,问题就会消失
use Sub::ScopeFinalizer qw( scope_finalizer );
{
my $backup = $Bar::BarVar;
my $guard = scope_finalizer { $Bar::BarVar = $backup };
$Bar::BarVar = 'modified';
Foo::foo();
}
可能存在更专门的工具。请参阅:
此列表中还有一项要添加。不要导出变量名。仅仅因为Exporter允许您这样做,并不意味着您应该这样做
@EXPORT_OK = qw($svar @avar %hvar); # DON'T!
导出变量不是一个好主意。它们可以在引擎盖下改变,在远距离引起可怕的影响,难以追踪和修复。相信我:他们不值得
为了提供设置/获取类范围设置的功能,最好将访问器作为子例程或类方法提供
这个规则有一个例外:如果你有常量变量(比如使用创建的变量),你可以导出它们,因为根据定义,它们不能在远处创建效果。同意,但我正在处理一些遗留代码:)尝试
print\$Foo::BarVar,\$Bar::BarVar代码>在本地
之前和之后。
use Sub::ScopeFinalizer qw( scope_finalizer );
{
my $backup = $Bar::BarVar;
my $guard = scope_finalizer { $Bar::BarVar = $backup };
$Bar::BarVar = 'modified';
Foo::foo();
}
@EXPORT_OK = qw($svar @avar %hvar); # DON'T!