这里发生的事情我不太明白.
> my @arr = <ac bc abc>
> @arr.grep: (( * ~~ /a/ ) && ( * ~~ /b/ ))
(bc abc)
Run Code Online (Sandbox Code Playgroud)
但
> @arr.grep(* ~~ /a/).grep(* ~~ /b/)
(abc)
Run Code Online (Sandbox Code Playgroud)
什么原因?
你已经提出了完美的解决方案.
另一个是:
my @arr = <ac bc abc>
@arr.grep: { $_ ~~ /a/ && $_ ~~ /b/ }
(abc)
Run Code Online (Sandbox Code Playgroud)
这个答案的其余部分只是解释了这个问题.这个问题的问题是WhateverStar &&WhateverStar所涉及的问题的更复杂版本.
如果逻辑运算符是代码,则它们不会执行它们的参数.
所以{ $_ ~~ /a/ } && { $_ ~~ /b/ }回报{ $_ ~~ /b/ }.
或者* ~~ /a/ && * ~~ /b/返回* ~~ /b/.
同时,如果它是代码或者它是正则表达式,它grep 是否执行它的匹配器,所以这些都是相同的:
foo.grep: { $_ ~~ /.../ }
foo.grep: * ~~ /.../;
foo.grep: /.../;
Run Code Online (Sandbox Code Playgroud)
Junctions 的魔力您的Junction解决方案看似自然 如果有人能解释我在下面遗漏的内容,我会喜欢它.虽然我预计它会起作用,但是我正在弯下腰来弄清楚它是如何工作的但是我认为它类似于(但并不完全):
foo & bar成为Junction中foo 和 bar.
尝试grep使用a Junction作为参数进行调用.
因为Junction它在正常值Any层次结构之外,所以大多数例程都没有匹配的签名.grep没有.
当您调用例程并且没有相应的签名时,初始调度失败,我们点击了调度回退处理程序.这可能是方法之一.
如果调度回退处理程序看到有Junction参数,那么它会提取单个值Junction并在逻辑上并发"线程"(当前从不是实际线程,但是如果它认为这是一个好主意,则允许编译器使它们成为真正的线程)对应于这些值.因此,它调用grep每个调用者元素两次,并将结果输出回Junction与传入相同类型的新元素Junction.
在布尔上下文中,Junction折叠为单个结果.
(如果a Junction在一个整体布尔上下文中,那么它可以(并行)基于结果的短路.如果它是一个any并且任何结果进来True然后它可以取消其余的 - 或者如果它实际上正在做的话不首先做它们事情是顺序的,就像现在一直如此.如果它是一个all并且任何结果进来False它可以取消其余的.等等.)