contains( Junction) 在哪里定义?

Where is contains( Junction) defined?

此代码有效:

(3,6...66).contains( 9|21 ).say  # OUTPUT: «any(True, True)␤»

和returns一个Junction. It's also tested, but not documented。 问题是我无法在任何地方找到它的实现。源代码中的 Str code, which is also called from Cool, never returns a Junction (it does not take a Junction, either). There are no other methods contain。 由于它是自动线程的,因此可能在某处专门定义了它。不过,我不知道在哪里。有帮助吗?

TL;DR 结点自动线程由一个中央机制处理。我在下面解释一下。

(你的问题的主体从你掉入陷阱开始,我认为你在一两年前记录了一个陷阱。这似乎与你真正要问的内容无关,但我也涵盖了这一点。)

如何处理联结

Where is contains( Junction) defined? ... The problem is I can't find [the Junctional] implementation anywhere. ... Since it's autothreaded, it's probably specially defined somewhere.

是的。有一种通用机制可以自动将自动线程应用于 所有 P6 例程(方法、运算符等),这些例程没有显式控制 Junction 参数发生的情况的签名。

只有极少数内置例程具有这些明确的 Junction 处理签名 -- print 可能是最值得注意的。用户定义的例程也是如此。

.contains没有有什么特殊处理。所以它是由通用机制自动处理的。

Junctions 的魔法 部分可能会对下面的低级细节进行高级描述。只需将您的 9|21 替换为该 SO 中的 foo & bar,将您的 .contains 替换为 grep,希望它有意义。

探索代码

我将专注于方法。其他例程以类似方式处理。

method AUTOTHREAD 完成完整 P6 方法的工作。

这是在 this code that sets up handling for both nqp and full P6 code 中设置的。

上面链接的P6设置代码依次调用setup_junction_fallback.

当用户程序中发生方法调用时,它涉及调用 find_method(模缓存命中,如该代码上方的注释中所述;请注意,在该代码中使用 "fallback" 一词评论是关于缓存未命中——这在技术上与我们正在探索的这段代码中明显的其他回退机制无关。

bit of code near the end of this find_method 处理(非缓存未命中)回退。

到达 find_method_fallback,从实际的联结处理开始。

陷阱

This code works:

(3,6...66).contains( 9|21 ).say  # OUTPUT: «any(True, True)␤»

它 "works" 在某种程度上也是如此:

(3,6...66).contains( 2 | '9 1' ).say  # OUTPUT: «any(True, True)␤»

参见 Lists become strings, so beware .contains() and/or discussion of the underlying issues such as pmichaud's comment

printput、中缀 ~.contains 等例程是 string 例程。这意味着他们将他们的论点强制为 Str。默认情况下,listy 值的 .Str 强制转换是由空格分隔的元素:

put 3,6...18;                    # 3 6 9 12 15 18
put (3,6...18).contains: '9 1';  # True

It's also tested

大概你的意思是两个带有 *.contains 参数的测试传递给 classify:

my $m := @l.classify: *.contains: any 'a'..'f';
my $s := classify *.contains( any 'a'..'f'), @l;

classify这样的例程是list例程。虽然一些列表例程在其列表 argument/invocant 上执行单个操作,例如 push,但其中大多数例程(包括 classify)会遍历列表并执行某些操作 with/to 列表中的每个元素

给定序列 invocant/argument,classify 将对其进行迭代并将每个元素传递给测试,在本例中为 *.contains.

后者随后会将 单个元素 强制转换为 Str。与您的示例相比,这是一个根本的区别,您的示例一次性将序列强制为 Str