我正在尝试查看在接收器上下文中抛出地图的方式。在这段代码中
class Sunk {
has $.titanic;
method sink {
say "Sinking $!titanic";
}
}
Sunk.new( :titanic($_) ) for 1..3;
(1..3).map: { Sunk.new( :titanic($_) ) };
Run Code Online (Sandbox Code Playgroud)
该for环路有效地下沉所有创建,则map没有。知道为什么吗?
这个烤测试:https : //github.com/perl6/roast/blob/b9bfe1844db25f65a4aeb351a0107f83689cb5c2/S04-statements/sink.t#L27-L32应该作为测试工作。地图实际上是在接收器上下文中,但我不知道它是如何“按沉没运行”的。它只是运行。
在您的示例中,map返回Seq带有Sunk对象的对象。整个Seq沉没,这有效地调用Seq.iterator.sink-all,这并没有下沉的所有元素:它只是拉Seq通过调用空pull-one,直到IterationEnd返回。
我不会解释太多,把大部分内容留到最后。
我正在尝试查看在接收器上下文中抛出地图的方式。
添加--> Nil作为块的返回值这样做:
(1..3).map: -> $_ --> Nil { Sunk.new( :titanic($_) ) }
Run Code Online (Sandbox Code Playgroud)
该
for环路有效地下沉所有创建,则map没有。
默认情况下,块运行:
除接收器上下文中的最后一个语句外的所有语句。
最后一条语句不在接收器上下文中。(最后一条语句是块的返回值,因此推测将其扔到接收器中是不合适的。)
你的代码没有改变你map调用的这个默认值,所以块的最后一条语句——它唯一的语句——不在接收器上下文中。(添加--> Nil到块的签名中会将最后一条语句放回到接收器上下文中。)
此默认方案的例外涉及某种语句关键字。for是其中之一——它把它的语句,或者它的块中的最后一个语句放在接收器上下文中。(要撤消该操作,使最后一条语句不在接收器上下文中,您可以编写类似$ = do for ....)
这个烘焙测试应该作为测试。并且
map有效地处于接收器上下文中,但我不知道它是如何“沉没运行”的。它只是运行。
我对相应的票证和测试感到困惑。所以,对不起,我不能帮助那个。
我做了几个小时的研究来准备这个答案。我发现并依赖的一些作品如下,以及我的简短笔记。
以下许多链接指向 IRC 日志的特定行。我对其中的大部分内容的意图是,您阅读每一行后面的一些对话,以最大限度地提高您从中获得的收益(即使它令人困惑,因为我认为即使这样也可能有所帮助,正如我接下来解释的那样)。
请考虑至少阅读下面的摘要,并单击一些链接,然后在此答案下发表评论以在此处引发进一步讨论,看看我们是否可以朝着清晰的方向发展。
Larry 开始在 STD (2010) 中实施接收器处理。包括主要是为了确立他开始将 raku 的接收器概念转化为代码形式(在 STD 解析器中)的点。
帕特里克要求澄清示例sub foo() { for @list { .say } }; foo(); 1(2010)。请关注帕特里克和拉里 (TimToady) 之间关于拉里想要什么的对话,而忽略侧轨。
TimToady:“接收器上下文对于找出令人敬畏的错误消息非常重要”(2012)。(我认为 raku 的接收器功能是一个极端折磨实现者的问题;参见下面的问题跟踪链接。)
jnthn:“请注意,急切上下文和接收器上下文是不同的。接收器上下文应该创建一个 for 循环(或映射)而不是构建结果列表”(2012)这是接收上下文的另一部分。这不仅仅是关于令人敬畏的错误消息;这也与性能有关。
TimToady:“我们甚至可以为“过程”设置单独的声明符,但只有接收器返回类型似乎已经说明了这一点”(他的意思是--> Nil)(2012 年)
jnthn 问道:“TimToady:对 https://rt.perl.org/Ticket/Display.html?id=126005 有什么感觉吗?基本上,像循环这样的东西会下沉他们的最后一条语句,所以循环块的计算结果为 Nil,所以 UNDO移相器开火。” (2015)(对实施者的更多折磨......)
rakudo/rakudo 中匹配搜索“zoffix sink”的几个未解决的问题;特别注意隐含下沉/&unwanted助手 #157票证中的缺陷。