这里发生的事情我不太了解。
> my @arr = <ac bc abc>
> @arr.grep: (( * ~~ /a/ ) && ( * ~~ /b/ ))
(bc abc)
但是
> @arr.grep(* ~~ /a/).grep(* ~~ /b/)
(abc)
是什么原因?
答案 0 :(得分:8)
您已经提出了完美的解决方案。
另一个可能是:
my @arr = <ac bc abc>
@arr.grep: { $_ ~~ /a/ && $_ ~~ /b/ }
(abc)
此答案的其余部分仅说明了问题。此问题中的问题是WhateverStar &&
WhateverStar中涵盖的问题的更复杂版本。
如果逻辑操作是代码,则逻辑操作不会执行其参数。
所以{ $_ ~~ /a/ } && { $_ ~~ /b/ }
返回{ $_ ~~ /b/ }
。
或者* ~~ /a/ && * ~~ /b/
返回* ~~ /b/
。
同时,grep
执行如果它是代码或正则表达式,则执行其匹配器,因此它们都是相同的:
foo.grep: { $_ ~~ /.../ }
foo.grep: * ~~ /.../;
foo.grep: /.../;
Junction
的魔力您的Junction
解决方案似乎很自然。如果有人可以在下面解释我的缺失,我将非常乐意。当我期望可以正常工作时,我很想知道它是如何工作的,但是我认为它有点像(但不太完全):
foo & bar
成为Junction
和 foo
的{{1}}。
试图使用bar
作为参数来调用grep
。
由于Junction
在常规Junction
值层次结构之外,因此大多数例程没有匹配的签名。 Any
没有。
当您调用例程并且没有相应的签名时,初始调度将失败,我们将遇到调度回退处理程序。 This可能是方法之一。
如果调度后备处理程序看到有grep
个参数,则它将提取Junction
中的各个值,并触发逻辑上并行的“线程”(当前从不 actual 线程,但是如果编译器认为这是一个不错的主意,允许它们使其成为真实的线程(对应于这些值)。因此,它会对发起方的每个元素调用Junction
两次,并将结果输出到与传入grep
相同类型的新Junction
中。
在布尔上下文中,Junction
折叠为单个结果。
(如果Junction
在整个布尔上下文中,则它可以基于结果(并行)短路。如果它是Junction
和 any 结果出现在any
中,那么它可以取消其余部分-或者如果它实际上是按顺序执行操作,则可以不首先执行它们,就像目前通常这样。如果是True
并且有任何结果在all
中可以取消其他内容。