本地和语句修饰符(例如后缀if)

时间:2018-03-29 22:44:09

标签: perl

perlsyn, "Statement-Modifiers" section明确指出

  

使用声明修改的mystateour的行为   修饰符条件或循环结构(例如,my $x if ...)是   未定义。

不幸的是,此列表缺少local,而its own documentation也无法覆盖其行为。我认为它也是未定义的,文档在这些特定部分中只是不完整。

这实际上是否包含在文档中?

1 个答案:

答案 0 :(得分:13)

my&上使用语句修饰符的未定义行为公司,如

my $x = 1  if $flag;  # UNDEFINED behavior

是因为my $x声明在编译时发生,而= 1赋值在运行时发生,测试也是如此。因此整个语句被打破了(它根本不应该分配吗?),这行代码的行为被认为是未定义的。

但是,local非常不同。来自perlsub(我的重点)

  

local 将其列出的变量修改为封闭块“evaldo FILE”的“本地” - 以及调用的任何子例程从那个区块内。本地只是为全局(意味着包)变量提供临时值。它不会创建局部变量。

因此,local执行的操作与myour完全不同;它为块的其余部分保存其目标(全局)变量的值,并在从块退出时恢复它。

此外,由于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 }对其余部分没有任何作用代码)。

这样做可能会根据单个条件的单纯值从根本上改变代码行为,并可能在更高级别改变代码行为;我建议仔细使用这些代码。这个简短的程序特别只显示了如何使用后缀条件 。感谢ysthikegami的评论。