为什么``终止''的行为与程序级别的范围中的``离开''会不同

  • 本文关键字:范围 离开 终止 程序 raku
  • 更新时间 :
  • 英文 :


我以为在一个程序的顶层中, 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';

重写

为什么will end的行为与will leave

不同

看起来will end的错误类似于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范围对应。

它们以不同的 dynamic 范围运行。留下块作为离开封闭块的一部分。在编译器完全完成您的代码并进行清理后,最终块运行:

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用于一种,另一个使用$_

最新更新