为什么`会结束`的行为与在程序级范围内“将离开”的行为不同?

时间:2017-09-14 13:28:02

标签: perl6

我认为在程序的顶层will endwill leave的行为方式相同,因为只有一个大的外部范围可以退出/离开。我认为任何一个都是检查变量最终值的好方法。

但是对于will end,它的行为就像变量从未被初始化一样:

my $foo will end { put "Final value for \$foo is '$_'"} = 'bar';

put "\$foo is now '$foo'";

$foo ~= ' baz';

输出

$foo is now 'bar'
Use of uninitialized value $_ of type Any in string context.
Methods .^name, .perl, .gist, or .say can be used to stringify it to something meaningful.
  in block  at phaser_end.p6 line 1
Final value for $foo is ''

但是,只需将will end更改为will leave即可实现我对其中任何一个的期望:

my $foo will leave { put "Final value for \$foo is '$_'"} = 'bar';

put "\$foo is now '$foo'";

$foo ~= ' baz';

输出

$foo is now 'bar'
Final value for $foo is 'bar baz'

为什么这里的行为存在差异?

我正在使用Rakudo-Star 2017.07。

更新

为了达到我期待will end的效果,我必须使用单独的END块:

END阻止:

my $foo = 'bar';

END { put "Final value for \$foo is '$foo'"};

put "\$foo is now '$foo'";

$foo ~= ' baz';

我想真正的问题归结为为什么END块的行为与will end块的行为不同。

will end阻止:

my $foo will end { put "Final value for \$foo is '$_'"} = 'bar';

put "\$foo is now '$foo'";

$foo ~= ' baz';

1 个答案:

答案 0 :(得分:2)

<强>重写

  

为什么will end的行为与will leave

不同

看起来will end有一个与this old and now resolved bug for will begin类似的错误。

除此之外,一切都按照我的预期运作:

my $leave will leave { say ['leave:', $_, OUTERS::<$leave>] } = 'leave';
my $end   will end   { say ['end:',   $_, OUTERS::<$end>]   } = 'end';
my $begin will begin { say ['begin:', $_, OUTERS::<$begin>] } = 'begin';
               END   { say ['END:',   $_, OUTERS::<$end>, $end] }

$_ = 999;

显示器

[begin: (Any) (Any)]
[leave: leave leave]
[END: 999 end end]
[end: 999 end]
  

具有will end的块的范围是否与具有will leave的块的范围不同?

它们具有与UNIT范围对应的相同外部lexical scope

他们在不同的dynamic scopes中运行。离开块作为离开封闭块的一部分。结束块运行after the compiler has completely finished with your code and is cleaning up

sub MAIN(@ARGS) {
    ...
    # UNIT scope -- your code -- is about to be created and compiled:
    $comp.command_line ...
    # UNIT scope no longer exists. We compiled it, ran it, and left it.
    ...
    # do all the necessary actions at the end, if any
    if nqp::gethllsym('perl6', '&THE_END') -> $THE_END {
        $THE_END()
    }
}
  

为什么END块的行为与will end块的行为不同?

因为您在一个中使用了$foo而在另一个中使用了$_