perlsyn
, "Statement-Modifiers" section明确指出
使用声明修改的
my
,state
或our
的行为 修饰符条件或循环结构(例如,my $x if ...
)是 未定义。
不幸的是,此列表缺少local
,而its own documentation也无法覆盖其行为。我认为它也是未定义的,文档在这些特定部分中只是不完整。
这实际上是否包含在文档中?
答案 0 :(得分:13)
在my
&上使用语句修饰符的未定义行为公司,如
my $x = 1 if $flag; # UNDEFINED behavior
是因为my $x
声明在编译时发生,而= 1
赋值在运行时发生,测试也是如此。因此整个语句被打破了(它根本不应该分配吗?),这行代码的行为被认为是未定义的。
但是,local
非常不同。来自perlsub(我的重点)
local
将其列出的变量修改为封闭块“eval
或do
FILE”的“本地” - 以及调用的任何子例程从那个区块内。本地只是为全局(意味着包)变量提供临时值。它不会创建局部变量。
因此,local
执行的操作与my
或our
完全不同;它为块的其余部分保存其目标(全局)变量的值,并在从块退出时恢复它。
此外,由于local
is a run-time operator没有与my $x = 1
一样的declare + assign的编译与运行时问题,因此可以使用后缀条件。考虑
use warnings;
use strict;
use feature 'say';
my $flag = @ARGV ? shift : 1;
our $var = 1;
{
local $var if $flag;
$var = 2;
say $var;
}
say $var;
使用$flag
设置(script.pl
)时,local
化会发生,最后一次打印显示全局our $var
已被保留。如果未设置标志(script.pl 0
),则不会发生全局值,也不会为该块保存全局值,并最终覆盖。
使用local $var = 2 if $flag;
,本地化和分配都不会发生。
如果只有local
语句本身必须以后缀方式进行,因为local
的效果仅在封闭范围内(因此if ($f) { local $var }
对其余部分没有任何作用代码)。
这样做可能会根据单个条件的单纯值从根本上改变代码行为,并可能在更高级别改变代码行为;我建议仔细使用这些代码。这个简短的程序特别只显示了如何使用后缀条件 。感谢ysth和ikegami的评论。