更新——乐道 2020.10
运行您的原始累加器代码(使用-nelinewise 标志)会得到以下结果。注意“final”这个词是如何出现在每一行的:
~$ perl6 -ne 'my @a; $_.split(",").kv.map: {@a[$^k]+=$^v}; say @a, " final"; ENTER {say "ENTER"}; BEGIN {say "BEGIN"}; LEAVE {say "LEAVE"}; END {say "END"};' drclaw.txt
BEGIN
ENTER
[1 1] final
[2 3] final
[3 6] final
LEAVE
END
-ne下面,使用标志背靠背运行基本上重复的脚本会产生一个有趣的结果。BEGIN, ENTER, LEAVE, 并END显示在完全相同的位置,按照每次调用一次的顺序重复:
~$ perl6 -ne 'my @a; .split(",").kv.map: {@a[$^k]+=$^v}; say @a, " final_a"; ENTER {say "ENTER"}; BEGIN {say "BEGIN"}; LEAVE {say "LEAVE"}; END {say "END"}; my @b; .split(",").kv.map: {@b[$^k]+=$^v}; say @b, " final_b"; ENTER {say "ENTER"}; BEGIN {say "BEGIN"}; LEAVE {say "LEAVE"}; END {say "END"};' drclaw.txt
BEGIN
BEGIN
ENTER
ENTER
[1 1] final_a
[1 1] final_b
[2 3] final_a
[2 3] final_b
[3 6] final_a
[3 6] final_b
LEAVE
LEAVE
END
END
但是,删除-ne下面的标志可以让您for lines() {...}在 Raku 代码本身内运行一个循环(单个脚本,而不是背靠背重复)。这个结果似乎更符合您的预期:
~$ perl6 -e 'my @a; for lines() {.split(",").kv.map: {@a[$^k]+=$^v};}; say @a, " final"; ENTER {say "ENTER"}; BEGIN {say "BEGIN"}; LEAVE {say "LEAVE"}; END {say "END"};' drclaw.txt
BEGIN
ENTER
[3 6] final
LEAVE
END
我认为对您的问题的简短回答是 Phasers 尊重块/循环语义,但在脚本方面受限于他们将向实施者报告多少次(显然每次调用只有一次)。但最终的区别在于,与没有命令行标志的内部循环相比,命令行标志对用户的返回是逐行的。-nefor lines() {...}-ne
最后,您始终可以使用中缀运算符强制重新加载$_主题变量。andthen也许这就是您一直在寻找的:
~$ perl6 -e 'my @a; for lines() {.split(",").kv.map: {@a[$^k]+=$^v} andthen $_.say }; say @a, " final"; ENTER {say "ENTER"}; BEGIN {say "BEGIN"}; LEAVE {say "LEAVE"}; END {say "END"};' drclaw.txt
BEGIN
ENTER
(1 1)
(2 3)
(3 6)
[3 6] final
LEAVE
END
[正在分析的测试文件,如下]。
~$ cat drclaw.txt
1,1
1,2
1,3
https://docs.raku.org/language/operators#index-entry-andthen