class Any is Mu {}

虽然 Mu 是 Raku 类层次结构的根,但 Any 是用作新类的默认基类的类,也是大多数内置类的基类。

由于 Raku 故意混淆了项目和单元素列表,因此 Any 中的大多数方法也存在于类 List 上,并强制转换为 List 或类似列表的类型。

方法§

方法 ACCEPTS§

multi method ACCEPTS(Any:D: Mu $other)

用法

EXPR.ACCEPTS(EXPR);

如果 $other === self(即它检查对象标识),则返回 True

许多内置类型会覆盖此方法以进行更具体的比较。

方法 any§

method any(--> Junction:D)

将调用者解释为列表,并从中创建一个 any-Junction

say so 2 == <1 2 3>.any;        # OUTPUT: «True␤» 
say so 5 == <1 2 3>.any;        # OUTPUT: «False␤»

方法 all§

method all(--> Junction:D)

将调用者解释为列表,并从中创建一个 all-Junction

say so 1 < <2 3 4>.all;         # OUTPUT: «True␤» 
say so 3 < <2 3 4>.all;         # OUTPUT: «False␤»

方法 one§

method one(--> Junction:D)

将调用者解释为列表,并从中创建一个 one-Junction

say so 1 == (123).one;      # OUTPUT: «True␤» 
say so 1 == (121).one;      # OUTPUT: «False␤»

方法 none§

method none(--> Junction:D)

将调用者解释为列表,并从中创建一个 none-Junction

say so 1 == (123).none;     # OUTPUT: «False␤» 
say so 4 == (123).none;     # OUTPUT: «True␤»

方法 list§

multi method list(Any:U:)
multi method list(Any:D \SELF:)

将中缀 , 运算符应用于调用者,并返回结果 List

say 42.list.^name;           # OUTPUT: «List␤» 
say 42.list.elems;           # OUTPUT: «1␤»

Any 的子类可以选择返回任何核心类型,该类型从 .list 执行 Positional 角色。使用 .List 强制专门转换为 List

@ 也可以用作列表或 Positional 上下文化器

my $not-a-list-yet = $[1,2,3];
say $not-a-list-yet.raku;             # OUTPUT: «$[1, 2, 3]␤» 
my @maybe-a-list = @$not-a-list-yet;
say @maybe-a-list.^name;              # OUTPUT: «Array␤» 

在第一种情况下,列表是项目化的。@ 作为前缀通过调用 .list 并将其转换为 Array 将初始标量置于列表上下文中。

方法 push§

multi method push(Any:U \SELF: |values --> Positional:D)

push 方法为未定义的调用者定义,并允许将未定义的值自动转换为空 Array,除非未定义的值已经实现了 Positional。然后,提供的参数将被推入新创建的 Array 中。

my %h;
say %h<a>;     # OUTPUT: «(Any)␤»      <-- Undefined 
%h<a>.push(1); # .push on Any 
say %h;        # OUTPUT: «{a => [1]}␤» <-- Note the Array

例程 reverse§

multi        reverse(*@list  --> Seq:D)
multi method reverse(List:D: --> Seq:D)

返回一个 Seq,其中包含相同元素,但顺序相反。

请注意,reverse 始终是指反转列表的元素;要反转字符串中的字符,请使用 flip

示例

say <hello world!>.reverse;     # OUTPUT: «(world! hello)␤» 
say reverse ^10;                # OUTPUT: «(9 8 7 6 5 4 3 2 1 0)␤»

方法 sort§

multi method sort()
multi method sort(&custom-routine-to-use)

使用 cmp 或给定的代码对象对可迭代对象进行排序,并返回一个新的 Seq。可选地,将 Callable 作为位置参数,指定如何排序。

示例

say <b c a>.sort;                           # OUTPUT: «(a b c)␤» 
say 'bca'.comb.sort.join;                   # OUTPUT: «abc␤» 
say 'bca'.comb.sort({$^b cmp $^a}).join;    # OUTPUT: «cba␤» 
say '231'.comb.sort(&infix:«<=>»).join;     # OUTPUT: «123␤» 
 
sub by-character-count { $^a.chars <=> $^b.chars }
say <Let us impart what we have seen tonight unto young Hamlet>.sort(&by-character-count);
# OUTPUT: «(us we Let what have seen unto young impart Hamlet tonight)␤»

例程 map§

multi method map(\SELF: &block)
multi        map(&code+values)

map 将迭代调用者,并根据每次调用的调用者中的代码对象的位数参数数量应用代码对象。代码对象的返回值将成为返回的 Seq 的元素。

:$label:$item 仅在内部有用,因为 for 循环会被转换为 map:$label 使用一个现有的 Label 来标记 .map 的循环,而 :$item 控制迭代是发生在 (SELF,) 上(如果设置了 :$item)还是 SELF 上。

sub 形式中,它将把 code 块应用于 values,这些 values 将用作调用者。

带有 |cIterable:D \iterableHash:D \hash 作为签名的形式将以 X::Cannot::Map 失败,主要用于捕获常见的陷阱。

在一个已经被下沉的 for 语句中,由 map 创建的 Seq 也会下沉。

say gather for 1 {
    ^3 .map: *.take;
} # OUTPUT: «(0 1 2)␤» 

在这种情况下,gather 会下沉 for 语句,下沉 Seq 的结果将是对其元素进行迭代,并对它们调用 .take

方法 deepmap§

method deepmap(&block --> Listis nodal

deepmap 将把 &block 应用于每个元素,并返回一个新的 List,其中包含 &block 的返回值,除非该元素具有 Iterable 角色。对于这些元素,deepmap 将递归地下降到子列表中。

say [[1,2,3],[[4,5],6,7]].deepmap(* + 1);
# OUTPUT: «[[2 3 4] [[5 6] 7 8]]␤»

对于 Associative,它将应用于其值。

{ what => "is"this => "thing"=> <real list> }.deepmap*.flip ).say
# OUTPUT: «{a => (laer tsil), this => gniht, what => si}␤» 

方法 duckmap§

method duckmap(&blockis rw is nodal

duckmap 将把 &block 应用于每个以这样一种方式表现的元素,即 &block 可以被应用。如果失败,它将尽可能递归地下降,否则将返回该项而不进行任何转换。如果对象是 Associative,它将作用于值。

<a b c d e f g>.duckmap(-> $_ where <c d e>.any { .uc }).say;
# OUTPUT: «(a b C D E f g)␤» 
(('d''e'), 'f').duckmap(-> $_ where <e f>.any { .uc }).say;
# OUTPUT: «((d E) F)␤» 
{ first => ('d''e'), second => 'f'}.duckmap(-> $_ where <e f>.any { .uc }).say;
# OUTPUT: «{first => (d E), second => F}␤» 

在第一种情况下,它被应用于 cde,它们是满足块({ .uc })应用条件的元素;其余元素按原样返回。

在第二种情况下,第一个元素是一个不满足条件的列表,因此它被访问;该扁平列表的行为将与第一个列表相同。在这种情况下

say [[1,2,3],[[4,5],6,7]].duckmap*² ); # OUTPUT: «[9 9]␤»

只要像数字一样表现,你就可以对任何东西进行平方。在这种情况下,有两个包含 3 个元素的数组;这些数组将被转换为数字 3 并进行平方。在下一种情况下,然而

say [[1,2,3],[[4,5],6.1,7.2]].duckmap-> Rat $_ { $_²} );
# OUTPUT: «[[1 2 3] [[4 5] 37.21 51.84]]␤»

3 个元素的列表不是 Rat,因此它递归地下降,但最终只对那些像 Rat 一样行走(或爬行,视情况而定)的元素应用操作。

虽然在表面上(和名称上),duckmap 可能看起来类似于 deepmap,但后者无论项目的类型如何,都会递归地应用。

方法 nodemap§

method nodemap(&block --> Listis nodal

nodemap 将把 &block 应用于每个元素,并返回一个新的 List,其中包含 &block 的返回值。与 deepmap 相反,如果它发现具有 Iterable 角色的元素,它不会递归地下降到子列表中。

say [[1,2,3], [[4,5],6,7], 7].nodemap(*+1);
# OUTPUT: «(4, 4, 8)␤» 
 
say [[23], [4, [56]]]».nodemap(*+1)
# OUTPUT: «((3 4) (5 3))␤»

如果我们使用 map 而不是 nodemap,上面的示例将产生完全相同的结果。两者之间的区别在于 map 会将 Slip 展平,而 nodemap 不会。

say [[2,3], [[4,5],6,7], 7].nodemap({.elems == 1 ?? $_ !! slip});
# OUTPUT: «(() () 7)␤» 
say [[2,3], [[4,5],6,7], 7].map({.elems == 1 ?? $_ !! slip});
# OUTPUT: «(7)␤»

当应用于 Associative 时,它将作用于值。

{ what => "is"this => "thing" }.nodemap*.flip ).say;
# OUTPUT: «{this => gniht, what => si}␤»

方法 flat§

method flat() is nodal

将调用者解释为一个列表,将 非容器化 Iterable 展平为一个扁平列表,并返回该列表。请记住,MapHash 类型是 Iterable,因此将被展平为成对的列表。

say ((12), (3), %(:42a));      # OUTPUT: «((1 2) 3 {a => 42})␤» 
say ((12), (3), %(:42a)).flat# OUTPUT: «(1 2 3 a => 42)␤»

请注意,Array 默认情况下会容器化其元素,因此 flat 不会展平它们。你可以使用

超方法调用 对所有内部 Iterable 调用 .List 方法,从而将它们去容器化,以便 flat 可以展平它们。

say [[123], [(45), 67]]      .flat# OUTPUT: «([1 2 3] [(4 5) 6 7])␤» 
say [[123], [(45), 67]]».List.flat# OUTPUT: «(1 2 3 4 5 6 7)␤»

有关更多微调选项,请参阅 deepmapduckmap签名解构

方法 eager§

method eager() is nodal

将调用者解释为一个 List,对其进行急切求值,并返回该 List

my  $range = 1..5;
say $range;         # OUTPUT: «1..5␤» 
say $range.eager;   # OUTPUT: «(1 2 3 4 5)␤»

方法 elems§

multi method elems(Any:U: --> 1)
multi method elems(Any:D:)

将调用者解释为一个列表,并返回列表中元素的数量。

say 42.elems;                   # OUTPUT: «1␤» 
say <a b c>.elems;              # OUTPUT: «3␤» 
say Whatever.elems ;            # OUTPUT: «1␤»

它也会为类返回 1。

方法 end§

multi method end(Any:U: --> 0)
multi method end(Any:D:)

将调用者解释为一个列表,并返回该列表的最后一个索引。

say 6.end;                      # OUTPUT: «0␤» 
say <a b c>.end;                # OUTPUT: «2␤»

方法 pairup§

multi method pairup(Any:U:)
multi method pairup(Any:D:)

如果调用者是一个类型对象,则返回一个空的 Seq

Range.pairup.say# OUTPUT: «()␤»

将调用者解释为一个列表,并从中构建一个 Pair 列表,与分配给 Hash 的方式相同。也就是说,它获取两个连续的元素并从中构建一个对,除非键位置的项目本身就是一个对(在这种情况下,该对将被传递,并且下一个列表项(如果有)被认为是一个键)。它返回一个 SeqPair

say (=> 1'b''c').pairup.raku;     # OUTPUT: «(:a(1), :b("c")).Seq␤»

子项§

multi item(\x)
multi item(|c)
multi item(Mu $a)

强制给定对象在项目上下文中求值,并返回其值。

say item([1,2,3]).raku;              # OUTPUT: «$[1, 2, 3]␤» 
say item( %apple => 10 ) ).raku;   # OUTPUT: «${:apple(10)}␤» 
say item("abc").raku;                # OUTPUT: «"abc"␤»

您也可以使用 $ 作为项目上下文化器。

say $[1,2,3].raku;                   # OUTPUT: «$[1, 2, 3]␤» 
say $("abc").raku;                   # OUTPUT: «"abc"␤»

方法 Array§

method Array(--> Array:Dis nodal

将调用者强制转换为 Array

方法 List§

method List(--> List:Dis nodal

使用 list 方法将调用者强制转换为 List

方法 serial§

multi method serial()

此方法是 Rakudo 特定的,未包含在 Raku 规范中。

该方法返回对实例本身的自引用。

my $b;                 # defaults to Any 
say $b.serial.^name;   # OUTPUT: «Any␤» 
say $b.^name;          # OUTPUT: «Any␤» 
my $breakfast = 'food';
$breakfast.serial.say# OUTPUT: «food␤» 

这显然是一个无操作,如上面的第三个示例所示。但是,在 HyperSeqRaceSeq 中,它返回一个序列化 Seq,因此可以将其视为 hyper/race 方法的相反。因此,它确保我们处于串行列表处理模式,而不是这些方法的自动线程模式。

方法 Hash§

multi method Hash--> Hash:D)

将调用者强制转换为 Hash

方法 hash§

multi method hash(Any:U:)
multi method hash(Any:D:)

当在类型对象上调用时,返回一个空的 Hash。在实例上,它等效于将调用者分配给一个 %- 标记的变量并返回它。

Any 的子类可以选择返回任何核心类型,该类型从 .hash 执行 Associative 角色。使用 .Hash 特别强制转换为 Hash

my $d# $d is Any 
say $d.hash# OUTPUT: {} 
 
my %m is Map = => 42=> 666;
say %m.hash;  # OUTPUT: «Map.new((a => 42, b => 666))␤» 
say %m.Hash;  # OUTPUT: «{a => 42, b => 666}␤» 

方法 Slip§

method Slip(--> Slip:Dis nodal

将调用者强制转换为 Slip

方法 Map§

method Map(--> Map:Dis nodal

将调用者强制转换为 Map

方法 Seq§

method Seq() is nodal

将调用者强制转换为 Seq

方法 Bag§

method Bag(--> Bag:Dis nodal

将调用者强制转换为 Bag,其中 Positional 被视为值的列表。

方法 BagHash§

method BagHash(--> BagHash:Dis nodal

将调用者强制转换为 BagHash,其中 Positional 被视为值的列表。

方法 Set§

method Set(--> Set:Dis nodal

将调用者强制转换为 Set,其中 Positional 被视为值列表。

方法 SetHash§

method SetHash(--> SetHash:Dis nodal

将调用者强制转换为 SetHash,其中 Positional 被视为值列表。

方法 Mix§

method Mix(--> Mix:Dis nodal

将调用者强制转换为 Mix,其中 Positional 被视为值列表。

方法 MixHash§

method MixHash(--> MixHash:Dis nodal

将调用者强制转换为 MixHash,其中 Positional 被视为值列表。

方法 Supply§

method Supply(--> Supply:Dis nodal

首先,它通过应用调用者的 .list 方法将其强制转换为 list,然后强制转换为 Supply

例程 min§

multi method min(&by?:$k:$v:$kv:$p )
multi        min(+args:&by:$k:$v:$kv:$p)

将调用者强制转换为 Iterable 并使用 cmp 语义返回最小元素;对于 MapHash,它返回具有最低值的 Pair

可以向 method 形式提供一个 Callable 位置参数。如果该 Callable 接受单个参数,则它将用于在进行比较之前转换要排序的值。原始值仍然是 min 返回的值。

如果该 Callable 接受两个参数,则它将用作比较器,而不是 cmp

sub 形式中,调用者作为参数传递,任何 Callable 都必须使用命名参数 :by 指定。

say (1,7,3).min();              # OUTPUT: «1␤» 
say (1,7,3).min({1/$_});        # OUTPUT: «7␤» 
say min(1,7,3);                 # OUTPUT: «1␤» 
say min(1,7,3,:by{ 1/$_ } )); # OUTPUT: «7␤» 
min( %(=> 3b=> 7 ) ).say ;  # OUTPUT: «a => 3␤»

从 2023.08 Rakudo 编译器版本开始,可以指定额外的命名参数以获取与最低值相关的所有可能信息。只要指定了任何这些命名参数,返回值始终List

  • :k

返回一个包含找到的最低值的索引的 List

  • :v

返回一个包含找到的最低值的实际值的 List。对于 MapHash,这些将是 Pair

  • :kv

返回一个包含索引和值的交替排列的 List

  • :p

返回一个包含 PairList,其中键是索引值,值是实际的最低值(对于 MapHash,这将是一个 Pair)。

say <a b c a>.min(:k);  # OUTPUT:«(0 3)␤» 
say <a b c a>.min(:v);  # OUTPUT:«(a a)␤» 
say <a b c a>.min(:kv); # OUTPUT:«(0 a 3 a)␤» 
say <a b c a>.min(:p);  # OUTPUT:«(0 => a 3 => a)␤»

例程 max§

multi method max(&by?:$k:$v:$kv:$p )
multi        max(+args:&by:$k:$v:$kv:$p)

max 方法/例程的接口与 min 的接口相同。但它将返回最高值,而不是最低值,这很明显。

say (1,7,3).max();                # OUTPUT: «7␤» 
say (1,7,3).max({1/$_});          # OUTPUT: «1␤» 
say max(1,7,3,:by{ 1/$_ } ));   # OUTPUT: «1␤» 
say max(1,7,3);                   # OUTPUT: «7␤» 
max( %(=> 'B'b=> 'C' ) ).say# OUTPUT: «b => C␤»

从 2023.08 Rakudo 编译器版本开始

say <a b c c>.max(:k);  # OUTPUT:«(2 3)␤» 
say <a b c c>.max(:v);  # OUTPUT:«(c c)␤» 
say <a b c c>.max(:kv); # OUTPUT:«(2 c 3 c)␤» 
say <a b c c>.max(:p);  # OUTPUT:«(2 => c 3 => c)␤»

例程 minmax§

multi method minmax()
multi method minmax(&by)
multi        minmax(+args:&by!)
multi        minmax(+args)

返回从最小元素到最大元素的 Range

如果提供了 Callable 位置参数,则每个值都会传递到过滤器中,并且会比较其返回值,而不是原始值。原始值仍然用于返回的 Range 中。

sub 形式中,调用者作为参数传递,并且可以使用命名参数 :by 指定比较 Callable

say (1,7,3).minmax();        # OUTPUT:«1..7␤» 
say (1,7,3).minmax({-$_});   # OUTPUT:«7..1␤» 
say minmax(1,7,3);           # OUTPUT: «1..7␤» 
say minmax(1,7,3,:by( -* )); # OUTPUT: «7..1␤»

方法 minpairs§

multi method minpairs(Any:D:)

调用 .pairs 并返回一个包含所有最小值的 Pair 的 Seq,由 cmp 运算符 判断。

<a b c a b c>.minpairs.raku.put# OUTPUT: «(0 => "a", 3 => "a").Seq␤» 
%(:42a, :75b).minpairs.raku.put# OUTPUT: «(:a(42),).Seq␤»

方法 maxpairs§

multi method maxpairs(Any:D:)

调用 .pairs 并返回一个包含所有最大值的 Pair 的 Seq,由 cmp 运算符 判断。

<a b c a b c>.maxpairs.raku.put# OUTPUT: «(2 => "c", 5 => "c").Seq␤» 
%(:42a, :75b).maxpairs.raku.put# OUTPUT: «(:b(75),).Seq␤»

方法 keys§

multi method keys(Any:U: --> List)
multi method keys(Any:D: --> List)

对于已定义的 Any,在调用 list 后返回其 ,否则调用 list 并返回它。

my $setty = Set(<Þor Oðin Freija>);
say $setty.keys# OUTPUT: «(Þor Oðin Freija)␤»

另请参阅 List.keys

尝试对类执行相同的操作将返回一个空列表,因为大多数类实际上没有键。

方法 flatmap§

method flatmap(&block:$label)

便捷方法,类似于 .map(&block).flat

方法 roll§

multi method roll(--> Any)
multi method roll($n --> Seq)

通过应用其 .list 方法将调用者强制转换为 list,并在其上使用 List.roll

my Mix $m = ("þ" xx 3"ð" xx 4"ß" xx 5).Mix;
say $m.roll;    # OUTPUT: «ð␤» 
say $m.roll(5); # OUTPUT: «(ß ß þ ß þ)␤»

在这种情况下,$m 被转换为列表,然后在其上滚动一个(加权的)骰子。有关更多信息,请参阅 List.roll

方法 iterator§

multi method iterator(Any:)

将对象转换为列表后,将其作为迭代器返回。这是 for 语句调用的函数。

.say for 3# OUTPUT: «3␤»

大多数子类重新定义此方法以进行优化,因此,实际上迭代的类型主要是那些实际上使用此实现的类型。

方法 pick§

multi method pick(--> Any)
multi method pick($n --> Seq)

通过应用其 .list 方法将调用者强制转换为 List,并在其上使用 List.pick

my Range $rg = 'α'..'ω';
say $rg.pick(3); # OUTPUT: «(β α σ)␤»

例程 skip§

multi method skip()
multi method skip(Whatever)
multi method skip(Callable:D $w)
multi method skip(Int() $n)
multi method skip($skip$produce)

从 1 项列表的迭代器创建 Seq,并在其上使用 Seq.skip,请检查该文档以了解实际用例;调用不带参数的 skip 等效于 skip(1)

multi skip(\skipper+values)

从 Rakudo 编译器 2022.07 版本开始,还存在 skip 的“sub”版本。它**必须**将跳过说明符作为第一个参数。其余参数将转换为 Seq,然后在其上调用 skip 方法。

方法 are§

multi method are(Any:)
multi method are(Any: Any $type)

Rakudo 编译器 2022.02 版本提供的无参数版本。带类型参数的版本在 6.e 语言版本中(Rakudo 编译器 2024.05+ 中存在早期实现)。

如果在没有参数的情况下调用,则返回最严格的类型(或角色),列表中的**所有**元素都将与之智能匹配。在空列表上返回 Nil

say (1,2,3).are;        # OUTPUT: «(Int)␤» 
say <a b c>.are;        # OUTPUT: «(Str)␤» 
say <42 666>.are;       # OUTPUT: «(IntStr)␤» 
say (42,666e0).are;     # OUTPUT: «(Real)␤» 
say (42,i).are;         # OUTPUT: «(Numeric)␤» 
say ("a",42,3.14).are;  # OUTPUT: «(Cool)␤» 
say ().are;             # OUTPUT: «Nil␤»

标量值被解释为单个元素列表。

say 42.are;             # OUTPUT: «(Int)␤» 
say Int.are;            # OUTPUT: «(Int)␤»

哈希将被解释为一对列表,因此将始终生成 Pair 类型对象。使用 .keys.values 方法获取哈希键或值的严格类型。

my %h = => 42=> "bar";
say %h.keys.are;        # OUTPUT: «(Str)␤» 
say %h.values.are;      # OUTPUT: «(Cool)␤»

如果带类型参数调用,则将检查调用者中的所有类型是否与给定类型智能匹配。如果是,则返回 True。如果任何智能匹配失败,则返回 Failure

say (1,2,3).are(Int);         # OUTPUT: «True␤» 
say <a b c>.are(Str);         # OUTPUT: «True␤» 
say <42 666>.are(Int);        # OUTPUT: «True␤» 
say <42 666>.are(Str);        # OUTPUT: «True␤» 
say (42,666e0).are(Real);     # OUTPUT: «True␤» 
say (42,i).are(Numeric);      # OUTPUT: «True␤» 
say ("a",42,3.14).are(Cool);  # OUTPUT: «True␤» 
say ().are;                   # OUTPUT: «True␤» 
 
Int.are(Str);      # OUTPUT: «Expected 'Str' but got 'Int'␤» 
(1,2,3).are(Str);  # OUTPUT: «Expected 'Str' but got 'Int' in element 0␤»

方法 prepend§

multi method prepend(Any:U: --> Array)
multi method prepend(Any:U: @values --> Array)

在空变量上不带参数调用时,它将其初始化为一个空的 Array;如果带参数调用,它将创建一个数组,然后在其上应用 Array.prepend

my $a;
say $a.prepend# OUTPUT: «[]␤» 
say $a;         # OUTPUT: «[]␤» 
my $b;
say $b.prepend(1,2,3); # OUTPUT: «[1 2 3]␤»

方法 unshift§

multi method unshift(Any:U: --> Array)
multi method unshift(Any:U: @values --> Array)

Any 变量初始化为空的 Array,并在其上调用 Array.unshift

my $a;
say $a.unshift# OUTPUT: «[]␤» 
say $a;         # OUTPUT: «[]␤» 
my $b;
say $b.unshift([1,2,3]); # OUTPUT: «[[1 2 3]]␤»

routine first§

multi method first(Bool:D $t)
multi method first(Regex:D $test:$end*%a)
multi method first(Callable:D $test:$end*%a is copy)
multi method first(Mu $test:$end*%a)
multi method first(:$end*%a)
multi        first(Bool:D $t|)
multi        first(Mu $test+values*%a)

通常,通过应用其 .list 方法将调用者强制转换为 list,并在其上使用 List.first

但是,这是一个具有不同签名的多方法,它们使用(略微)不同的行为实现,尽管将其用作子例程等效于将其用作具有第二个参数作为对象的方法。

首先,使用 Bool 作为参数将始终返回 Failure。使用 $test 的形式将返回与之智能匹配的第一个元素,如果使用 :end,则从末尾开始。

say (3..33).first;           # OUTPUT: «3␤» 
say (3..33).first(:end);     # OUTPUT: «33␤» 
say (⅓,⅔…30).first0xF );   # OUTPUT: «15␤» 
say first 0xF, (⅓,⅔…30);     # OUTPUT: «15␤» 
say (3..33).first( /\d\d/ ); # OUTPUT: «10␤»

第三和第四个示例使用 Mu $test 形式,它们智能匹配并返回第一个匹配的元素。最后一个示例使用正则表达式作为测试,用于表示两位数,因此第一个满足该条件的数字是 10。最后一种形式使用 Callable 多方法。

say (⅓,⅔…30).first* %% 11:end:kv ); # OUTPUT: «(65 22)␤»

此外,对第一个元素的搜索将从 :end 开始,并返回一个列表中的键/值集;在这种情况下, 只是它在 Seq 中所占的位置。:kv 参数(它是上面定义中 %a 参数的一部分)修改了 first 的返回值,将其提供为键和值的扁平化列表;对于列表对象,键始终是索引。

从 6.d 版本开始,测试也可以是 Junction

say (⅓,⅔…30).first3 | 33:kv ); # OUTPUT: «(8 3)␤»

method unique§

multi method unique()
multi method unique:&as!:&with! )
multi method unique:&as! )
multi method unique:&with! )

创建一个唯一元素的序列,这些元素可以是对象本身的元素,也可以是作为 sub 调用时 values 中的元素。

<1 2 2 3 3 3>.unique.say# OUTPUT: «(1 2 3)␤» 
say unique <1 2 2 3 3 3># OUTPUT: «(1 2 3)␤»

:as:with 参数接收函数,这些函数用于在检查相等性之前转换项目,以及用于检查相等性,因为默认情况下使用 === 运算符。

("1"1""2).uniqueas => Intwith => &[==] ).say# OUTPUT: «(1 2)␤»

请参阅 unique,以获取使用其子形式的其他示例。

method repeated§

multi method repeated()
multi method repeated:&as!:&with! )
multi method repeated:&as! )
multi method repeated:&with! )

unique 类似,在 values(作为例程)或对象中查找重复元素,使用 :as 关联参数作为规范化函数,使用 :with 作为相等性函数。

<1 -1 2 -2 3>.repeated(:as(&abs),:with(&[==])).say# OUTPUT: «(-1 -2)␤» 
(3+3i, 3+2i, 2+1i).repeated(as => *.re).say;        # OUTPUT: «(3+2i)␤»

它返回规范化之前的最后一个重复元素,如上面的示例所示。请参阅 repeated,以获取使用其子形式的更多示例。

method squish§

multi method squish:&as!:&with = &[===] )
multi method squish:&with = &[===] )

类似于 .repeated,返回连续相等元素序列的第一个元素的序列,如果存在,则通过函数 :as 进行规范化,并使用 :with 参数或默认的 === 作为相等性运算符。

"aabbccddaa".comb.squish.say;             # OUTPUT: «(a b c d a)␤» 
"aABbccdDaa".comb.squish:as(&lc) ).say# OUTPUT: «(a B c d a)␤» 
(3+2i,3+3i,4+0i).squishas => *.rewith => &[==]).put# OUTPUT: «3+2i 4+0i␤» 

如最后一个示例所示,序列可以包含单个元素。请参阅 squish,以获取其他 sub 示例。

method permutations§

method permutations(|c)

通过应用其 .list 方法将调用者强制转换为 list,并在其上使用 List.permutations

say <a b c>.permutations;
# OUTPUT: «((a b c) (a c b) (b a c) (b c a) (c a b) (c b a))␤» 
say set(1,2).permutations;
# OUTPUT: «((2 => True 1 => True) (1 => True 2 => True))␤»

对具有单个元素或没有元素的数据结构的排列将返回一个列表,该列表包含一个空列表或一个包含单个元素的列表。

say 1.permutations# OUTPUT: «((1))␤»

method join§

method join($separator = ''is nodal

通过调用 self.list 将对象转换为列表,并在列表上调用 .join。可以接受一个分隔符,默认情况下为空字符串。

(1..3).join.say;       # OUTPUT: «123␤» 
<a b c>.join("").put# OUTPUT: «a❧b❧c␤»

routine categorize§

multi method categorize()
multi method categorize(Whatever)
multi method categorize($test:$into!:&as)
multi method categorize($test:&as)
multi        categorize($test+items:$into!*%named )
multi        categorize($test+items*%named )

第一种形式将始终失败。第二种形式根据给定对象的标识进行分类,这通常只有与 :&as 参数结合使用时才有意义。

在最简单的形式中,它使用一个 $test,其结果将用作键;键的值将是产生该键作为测试结果的元素的数组。

say (1..13).categorize* %% 3);
say categorize* %% 31..13)
# OUTPUT: «{False => [1 2 4 5 7 8 10 11 13], True => [3 6 9 12]}␤» 

:as 参数将在分类之前进行规范化。

say categorize* %% 3-5..5as => &abs )
# OUTPUT: «{False => [5 4 2 1 1 2 4 5], True => [3 0 3]}␤» 

$into 关联参数可用于将结果放入其中,而不是返回新的 Hash

my %leap-years;
my @years = (2002..2009).map{ Date.new$_~"-01-01" ) } );
@years.categorize*.is-leap-year , into => %leap-years );
say %leap-years
# OUTPUT: 
# «{ False 
# => [2002-01-01 2003-01-01 2005-01-01 2006-01-01 2007-01-01 2009-01-01], 
#    True => [2004-01-01 2008-01-01]}␤» 

用于分类的函数可以返回一个数组,指示其参数可以放入的所有可能的箱子。

sub divisible-byInt $n --> Array(Seq) ) {
    gather {
        for <2 3 5 7> {
            take $_ if $n %% $_;
        }
    }
}
 
say (3..13).categorize&divisible-by );
# OUTPUT: 
# «{2 => [4 6 8 10 12], 3 => [3 6 9 12], 5 => [5 10], 7 => [7]}␤» 

在这种情况下,范围内的每个数字都被分类到尽可能多的箱子中。

在 Rakudo 编译器版本 2023.02 中添加了对使用 Whatever 作为测试的支持。

routine classify§

multi method classify()
multi method classify(Whatever)
multi method classify($test:$into!:&as)
multi method classify($test:&as)
multi        classify($test+items:$into!*%named )
multi        classify($test+items*%named )

第一种形式将始终失败。第二种形式根据给定对象的标识进行分类,这通常只有与 :&as 参数结合使用时才有意义。

其余部分包括一个 $test 参数,它是一个函数,将为每个输入返回一个标量;这些将用作哈希的键,其值将是包含对测试函数输出该键的元素的数组。

my @years = (2003..2008).map{ Date.new$_~"-01-01" ) } );
@years.classify*.is-leap-year , into => my %leap-years );
say %leap-years;
# OUTPUT: «{False => [2003-01-01 2005-01-01 2006-01-01 2007-01-01], 
#           True => [2004-01-01 2008-01-01]}␤» 

类似于 .categorize,元素可以通过 :as 参数传递的 Callable 进行规范化,并且可以使用 :into 命名参数传递一个 Hash,结果将被分类到其中;在上面的示例中,它是动态定义的。

从 6.d 版本开始,.classify 也将适用于 Junction

在 Rakudo 编译器版本 2023.02 中添加了对使用 Whatever 作为测试的支持。

routine reduce§

multi method reduce(Any:U: & --> Nil)
multi method reduce(Any:D: &with)
multi        reduce (&with+list)

此例程通过应用二元子例程来组合列表状对象中的元素,并产生单个结果。它将它的参数(或子形式的第一个参数)作为运算符应用于对象中的所有元素(或子形式的第二个参数),产生单个结果。子例程必须是 中缀运算符 或接受两个位置参数。当使用中缀运算符时,我们必须提供其子例程版本的代码对象,即运算符类别,后跟冒号,然后是包含构成运算符的符号的列表引用构造(例如,infix:<+>)。参见 运算符

say (1..4).reduce(&infix:<+>);   # OUTPUT: «10␤» 
say reduce &infix:<+>1..4;     # OUTPUT: «10␤» 
say reduce &min1..4;           # OUTPUT: «1␤» 
 
sub hyphenate(Str \aStr \b{ a ~ '-' ~ b }
say reduce &hyphenate'a'..'c'# OUTPUT: «a-b-c␤»

应用于类时,例程将始终返回 Nil

say Range.reduce(&infix:<+>);    # OUTPUT: «Nil␤» 
say Str.reduce(&infix:<~>);      # OUTPUT: «Nil␤»

参见 List.reduce 以获得更详细的讨论。

routine produce§

multi method produce(Any:U: & --> Nil)
multi method produce(Any:D: &with)
multi        produce (&with+list)

这类似于 reduce,但返回一个包含累积值的列表,而不是单个结果。

<10 5 3>.reduce( &[*] ).say ; # OUTPUT: «150␤» 
<10 5 3>.produce( &[*] ).say# OUTPUT: «(10 50 150)␤» 

生成的列表的最后一个元素将是 .reduce 方法产生的输出。

如果它是一个类,它将简单地返回 Nil。

method pairs§

multi method pairs(Any:U:)
multi method pairs(Any:D:)

如果调用者是类型对象,则返回一个空的 List

say Num.pairs# OUTPUT: «()␤»

对于值对象,它通过 list 方法将调用者转换为 List,并返回 List.pairs 对其的结果。

<1 2 2 3 3 3>.Bag.pairs.say;# OUTPUT: «(1 => 1 3 => 3 2 => 2)␤»

在这种情况下,包中的每个元素(带权重)都被转换为一个对。

method antipairs§

multi method antipairs(Any:U:)
multi method antipairs(Any:D:)

如果调用者是类型对象,则返回一个空的 List

Range.antipairs.say# OUTPUT: «()␤»

如果它是一个值对象,它将在将其转换为一对列表后返回反转的对列表;值将成为键,反之亦然。

%(=> 1t=> 2=> 3).antipairs.say ;# OUTPUT: «(2 => t 1 => s 3 => u)␤»

method invert§

multi method invert(Any:U:)
multi method invert(Any:D:)

应用于类型对象将返回一个空列表;应用于对象将将其转换为列表并应用 List.invert 到它,也就是说,在每个对中交换键和值。生成的列表需要是一个 Pair 列表。

"aaabbcccc".comb.Bag.invert.say# OUTPUT: «(4 => c 3 => a 2 => b)␤»

在这种情况下,Bag 可以转换为 Pair 列表。如果将对象转换为列表的结果不是一对列表,则该方法将失败。

routine kv§

multi method kv(Any:U:)
multi method kv(Any:D:)
multi        kv($x)

如果调用者是类型对象,则返回一个空的 List

Sub.kv.say ;# OUTPUT: «()␤»

它对调用者调用 list 以获取值对象,并返回 List.kv 对其的结果,作为一个列表,其中键和值将被排序并相邻

<1 2 3>.kv.say# OUTPUT: «(0 1 1 2 2 3)␤»

Positional 的情况下,索引将被视为

method toggle§

method toggle(Any:D: *@conditions where .all ~~ Callable:DBool :$off  --> Seq:D)

迭代 调用者,产生一个 Seq,切换接收到的值是否根据 @conditions 中调用 Callables 的结果在结果中传播。

say (1..15).toggle(* < 5, * > 10* < 15); # OUTPUT: «(1 2 3 4 11 12 13 14)␤» 
say (1..15).toggle(:off* > 2* < 5, * > 10* < 15); # OUTPUT: «(3 4 11 12 13 14)␤» 

想象一个开关,它要么打开要么关闭(TrueFalse),如果它打开,则会产生值。默认情况下,该开关的初始状态为“打开”位置,除非 :$off 设置为真值,在这种情况下,初始状态将为“关闭”。

@conditions 的开头获取一个 Callable(如果有的话),它将成为当前测试器。原始序列中的每个值都通过调用测试器 Callable 并传入该值来进行测试。我们想象中的开关状态设置为测试器的返回值:如果返回值为真,则将开关设置为“开”,否则设置为“关”。

每当开关切换(即从“关”切换到“开”或从“开”切换到“关”)时,当前测试器 Callable 将被 @conditions 中的下一个 Callable 替换(如果有),该测试器将用于测试任何进一步的值。如果没有更多测试器 Callable 可用,则开关将保持其当前状态,直到迭代结束。

# our original sequence of elements: 
say list ^10# OUTPUT: «(0 1 2 3 4 5 6 7 8 9)␤» 
# toggled result: 
say ^10 .toggle: * < 4* %% 2&is-prime# OUTPUT: «(0 1 2 3 6 7)␤» 
 
# First tester Callable is `* < 4` and initial state of switch is "on". 
# As we iterate over our original sequence: 
# 0 => 0 < 4 === True  switch is on, value gets into result, switch is 
#                      toggled, so we keep using the same Callable: 
# 1 => 1 < 4 === True  same 
# 2 => 2 < 4 === True  same 
# 3 => 3 < 4 === True  same 
# 4 => 4 < 4 === False switch is now off, "4" does not make it into the 
#                      result. In addition, our switch got toggled, so 
#                      we're switching to the next tester Callable 
# 5 => 5 %% 2 === False  switch is still off, keep trying to find a value 
# 6 => 6 %% 2 === True   switch is now on, take "6" into result. The switch 
#                        toggled, so we'll use the next tester Callable 
# 7 => is-prime(7) === True  switch is still on, take value and keep going 
# 8 => is-prime(8) === False switch is now off, "8" does not make it into 
#                            the result. The switch got toggled, but we 
#                            don't have any more tester Callables, so it 
#                            will remain off for the rest of the sequence. 

由于开关状态的切换会加载下一个测试器 Callable,因此将 :$off 设置为 True 值会影响第一个测试器被丢弃的时间。

# our original sequence of elements: 
say <0 1 2># OUTPUT: «(0 1 2)␤» 
# toggled result: 
say <0 1 2>.toggle: * > 1# OUTPUT: «()␤» 
 
# First tester Callable is `* > 1` and initial state of switch is "on". 
# As we iterate over our original sequence: 
# 0 => 0 > 1 === False  switch is off, "0" does not make it into result. 
#                      In addition, switch got toggled, so we change the 
#                      tester Callable, and since we don't have any more 
#                      of them, the switch will remain "off" until the end 

当使用 :off 时,行为会发生变化。

# our original sequence of elements: 
say <0 1 2># OUTPUT: «(0 1 2)␤» 
# toggled result: 
say <0 1 2>.toggle: :off* > 1# OUTPUT: «(2)␤» 
 
# First tester Callable is `* > 1` and initial state of switch is "off". 
# As we iterate over our original sequence: 
# 0 => 0 > 1 === False  switch is off, "0" does not make it into result. 
#                       The switch did NOT get toggled this time, so we 
#                       keep using our current tester Callable 
# 1 => 1 > 1 === False  same 
# 2 => 2 > 1 === True   switch is on, "2" makes it into the result 

例程头部§

multi method head(Any:D:is raw
multi method head(Any:D: Callable:D $w)
multi method head(Any:D: $n)

返回对象中的第一个元素,或者如果使用了 $n,则返回前 $n 个元素。

"aaabbc".comb.head.put# OUTPUT: «a␤» 
say ^10 .head(5);           # OUTPUT: «(0 1 2 3 4)␤» 
say ^∞ .head(5);            # OUTPUT: «(0 1 2 3 4)␤» 
say ^10 .head;              # OUTPUT: «0␤» 
say ^∞ .head;               # OUTPUT: «0␤»

在前两种情况下,结果不同,因为 Mix 中没有定义的顺序。在其他情况下,它返回一个 Seq。可以使用 Callable 返回除最后一个元素之外的所有元素。

say (^10).head* - 3 );# OUTPUT: «(0 1 2 3 4 5 6)␤»

从 Rakudo 编译器的 2022.07 版本开始,还有一个 head 的“子”版本。

multi head(\specifier+values)

必须将头部说明符作为第一个参数。其余参数将被转换为 Seq,然后调用其 head 方法。

例程尾部§

multi method tail() is raw
multi method tail($n)

返回对象的最后一个元素或 $n 个最后一个元素的列表。$n 可以是 Callable,通常是 WhateverCode,它将用于获取对象中除前 n 个元素之外的所有元素。

say (^12).reverse.tail ;     # OUTPUT: «0␤» 
say (^12).reverse.tail(3);   # OUTPUT: «(2 1 0)␤» 
say (^12).reverse.tail(*-7); # OUTPUT: «(4 3 2 1 0)␤» 

从 Rakudo 编译器的 2022.07 版本开始,还有一个 tail 的“子”版本。

multi tail(\specifier+values)

必须将尾部说明符作为第一个参数。其余参数将被转换为 Seq,然后调用其 tail 方法。

方法树§

multi method tree(Any:U:)
multi method tree(Any:D:)
multi method tree(Any:D: Whatever )
multi method tree(Any:D: Int(Cool$count)
multi method tree(Any:D: @ [&first*@rest])
multi method tree(Any:D: &first*@rest)

如果未定义或不是 Iterable,则返回类,否则返回将其 tree 方法应用于其调用者的结果。

say Any.tree# OUTPUT: «Any␤»

.treeIterable 元素有不同的原型。

my @floors = ( 'A', ('B','C', ('E','F','G')));
say @floors.tree(1).flat.elems# OUTPUT: «6␤» 
say @floors.tree(2).flat.elems# OUTPUT: «2␤» 
say @floors.tree*.join("-"),*.join(""),*.join("|"));# OUTPUT: «A-B—C—E|F|G␤» 

对于数字,它会迭代地将 tree 应用于较低级别的每个元素;第一个实例将对数组中的每个元素应用 .tree(0),下一个示例也是如此。

第二个原型将作为参数传递的 WhateverCode 应用于每个级别;第一个参数将进入级别 1,依此类推。因此,tree 可以成为处理复杂的多级数据结构的所有级别的绝佳方法。

方法 nl-out§

method nl-out(--> Str)

返回值为 "\n" 的 Str。有关详细信息,请参见 IO::Handle.nl-out

Num.nl-out.print;     # OUTPUT: «␤» 
Whatever.nl-out.print;# OUTPUT: «␤» 
33.nl-out.print;      # OUTPUT: «␤»

方法 combinations§

method combinations(|c)

通过应用其 .list 方法将调用者强制转换为 list,并在其上使用 List.combinations

say (^3).combinations# OUTPUT: «(() (0) (1) (2) (0 1) (0 2) (1 2) (0 1 2))␤» 

对空数据结构的组合将返回一个包含单个元素的列表,即空列表;对包含单个元素的数据结构,它将返回一个包含两个列表的列表,其中一个为空,另一个包含单个元素。

say set().combinations# OUTPUT: «(())␤»

方法 grep§

method grep(Mu $matcher:$k:$kv:$p:$v --> Seq)

通过应用其 .list 方法将调用者强制转换为 list,并在其上使用 List.grep

对于未定义的调用者,根据 $matcher,返回值可以是 ((Any)) 或空列表。

my $a;
say $a.grep({ True }); # OUTPUT: «((Any))␤» 
say $a.grep({ $_ });   # OUTPUT: «()␤»

方法 append§

multi method append(Any:U \SELF: |values)

如果实例不是位置事物,则将其实例化为一个新的 Array,否则克隆当前实例。之后,它将作为参数传递的值追加到通过对其调用 Array.append 获得的数组中。

my $a;
say $a.append# OUTPUT: «[]␤» 
my $b;
say $b.append((1,2,3)); # OUTPUT: «[1 2 3]␤»

方法值§

multi method values(Any:U:)
multi method values(Any:D:)

对于未定义或类参数,将返回一个空列表,否则将对象转换为列表。

say (1..3).values# OUTPUT: «(1 2 3)␤» 
say List.values;   # OUTPUT: «()␤»

方法 collate§

method collate()

collate 方法在排序时会考虑 Unicode 图形字符的特性;也就是说,排序方式与人们的预期基本一致,而不是使用代码点出现的顺序。如果 collate 应用于的对象是 Iterable,它将以这种方式运行。

say ('a''Z').sort# (Z a) 
say ('a''Z').collate# (a Z) 
say <ä a o ö>.collate# (a ä o ö) 
my %hash = 'aa' => 'value''Za' => 'second';
say %hash.collate# (aa => value Za => second); 

此方法受 $*COLLATION 变量的影响,该变量配置四个 排序级别。虽然主、次和三级排序对于不同的脚本意味着不同的东西,但对于英语使用的拉丁脚本,它们主要对应于主排序是字母顺序,次排序是变音符号,三级排序是大小写。

在下面的示例中,您可以看到当我们禁用三级排序(在拉丁脚本中通常用于大小写),并禁用四级排序(通过检查字符串的代码点值来打破任何联系)时,我们为 Aa 获得了 相同 的结果。

$*COLLATION.set(:quaternary(False), :tertiary(False));
say 'a' coll 'A'# OUTPUT: «Same␤» 
say ('a','A').collate == ('A','a').collate# OUTPUT: «True␤»

该变量会影响 coll 运算符,如所示,以及此方法。

方法 cache§

method cache()

提供对象的 List 表示形式,在实例上调用 list 方法。

方法 batch§

multi method batch(Int:D $batch)
multi method batch(Int:D :$elems!)

通过应用其 .list 方法将调用者强制转换为 list,并在其上使用 List.batch

方法 rotor§

multi method rotor(Any:D: Int:D $batch:$partial)
multi method rotor(Any:D: *@cycle:$partial)

创建一个 Seq,将对象中的元素分组到包含 $batch 个元素的列表中。

say (3..9).rotor(3); # OUTPUT: «((3 4 5) (6 7 8))␤»

使用 :partial 命名参数,它还将包含没有达到 $batch 大小的列表。

say (3..10).rotor(3:partial); # OUTPUT: «((3 4 5) (6 7 8) (9 10))␤»

.rotor 可以使用整数和对的数组调用,这些数组将依次应用。虽然整数将建立批次大小(如上所述),但 Pair 将使用键作为批次大小,并将值作为要跳过的元素数量(如果为正),或重叠数量(如果为负)。

say (3..11).rotor(32 => 13 => -2:partial);
# OUTPUT: «((3 4 5) (6 7) (9 10 11) (10 11))␤»

在这种情况下,第一个批次(由整数控制)包含 3 个元素;第二个批次包含 2 个元素(对的键),但跳过一个(数字 8);第三个批次的大小为 2(因为允许部分),并且重叠也为 2。

重叠不能大于子列表大小;在这种情况下,它将抛出一个 Exception

say (3..11).rotor(32 => 13 => -4:partial);
# OUTPUT: «(exit code 1) Rotorizing gap is out of range. Is: -4, should be in 
# -3..^Inf; ␤Ensure a negative gap is not larger than the length of the 
# sublist␤ ␤␤» 

$batch 的非 Int 值将被强制转换为 Int。

say (3..9).rotor(3+⅓); # OUTPUT: «((3 4 5) (6 7 8))␤»

另请参阅 list.rotor 以获取应用于列表的示例。

方法 sum§

method sum() is nodal

如果内容是可迭代的,它将返回逐个提取值后的总和,如果列表为空,则返回 0。

(3,2,1).sum# OUTPUT: «6␤» 
say 3.sum;   # OUTPUT: «3␤» 

如果任何元素无法转换为数字,它将失败。

多方法 slice§

method slice(Any:D: *@indices --> Seq:D)

从 Rakudo 编译器 2021.02 版本开始可用。

将调用者转换为 Seq,然后在其上调用 slice 方法

say (1..10).slice(03..68);  # OUTPUT: «(1 4 5 6 7 9)␤»

例程 snip§

multi        snip(\matcher+values)
multi method snip(\values: \matcher)

从 6.e 语言版本开始可用(早期实现存在于 Rakudo 编译器 2022.07+ 中)。

snip 方法/子例程提供了一种将给定的 Iterable 切割成两个或多个 List 的方法。只要给定 Iterable 中的值的智能匹配返回 False,就会进行“剪切”。匹配器也可以是匹配器列表:只要进行了一次“剪切”,它就会开始使用下一个匹配器进行检查。如果不再有匹配器,将生成 Iterable 的其余部分。

.say for snip * < 10251396;      # OUTPUT: «(2 5)␤(13 9 6)␤» 
.say for snip (* < 10* < 20), 51329# OUTPUT: «(5)␤(13)␤(29)␤» 
.say for snip Int255"a""b";      # OUTPUT: «(2 5 5)␤(a b)␤» 
.say for (251396).snip(* < 10);    # OUTPUT: «(2 5)␤(13 9 6)␤» 
.say for (513,29).snip(* < 10* < 20);  # OUTPUT: «(5)␤(13)␤(29)␤» 
.say for (255"a""b").snip: Int;    # OUTPUT: «(2 5 5)␤(a b)␤» 

例程 snitch§

multi  snitch(\snitchee)
multi  snitch(&snitcher, \snitchee)
method snitch(\snitchee: &snitcher = &note)

从 6.e 语言版本开始可用(早期实现存在于 Rakudo 编译器 2022.12+ 中)。

snitch 方法/子例程是一个调试/日志记录工具,它将始终以不变的形式返回任何调用者/参数。

默认情况下,它会记录调用者/参数,但可以通过指定一个Callable来覆盖,该Callable期望将调用者/参数作为其唯一参数。

(my $a = 42).snitch = 666say $a;  # OUTPUT: «42␤666␤» 
(1..5).snitch;                      # OUTPUT: «1..5␤» 
(1..5).Seq.snitch;                  # OUTPUT: «(1 2 3 4 5)␤» 
(1..5).Seq.snitch(&dd);             # OUTPUT: «(1, 2, 3, 4, 5).Seq␤» 
(1..5).map(*+1).snitch;             # OUTPUT: «(2 3 4 5 6)␤» 
say (1..3).Seq.snitch.map(*+2);     # OUTPUT: «(1 2 3)␤(3 4 5)␤» 

相同,使用 feed 运算符

(1..3).Seq ==> snitch() ==> map(*+2==> say();  # OUTPUT: «(1 2 3)␤(3 4 5)␤» 

使用自定义日志记录器

my @snitched;
my @result = (1..3).Seq.snitch({ @snitched.push($_}).map(*+2);
say @snitched;  # OUTPUT: «[(1 2 3)]␤» 
say @result;    # OUTPUT: «[3 4 5]␤» 

类型图§

Any 的类型关系
raku-type-graph cluster: Mu children cluster: Pod:: top level cluster: Date/time handling cluster: Collection roles Any Any Mu Mu Any->Mu Junction Junction Junction->Mu Pod::Config Pod::Config Pod::Config->Any Pod::Block Pod::Block Pod::Block->Any Date Date Date->Any Dateish Dateish Date->Dateish DateTime DateTime DateTime->Any DateTime->Dateish DateTime-local-timezone DateTime-local-timezone Positional Positional Associative Associative Baggy Baggy QuantHash QuantHash Baggy->QuantHash AST AST AST->Any Cool Cool Cool->Any Stringy Stringy Str Str Str->Cool Str->Stringy Allomorph Allomorph Allomorph->Str Iterable Iterable List List List->Positional List->Cool List->Iterable Array Array Array->List Attribute Attribute Attribute->Any Backtrace Backtrace Backtrace->Any Backtrace::Frame Backtrace::Frame Backtrace::Frame->Any QuantHash->Associative Bag Bag Bag->Any Bag->Baggy BagHash BagHash BagHash->Any BagHash->Baggy Blob Blob Blob->Positional Blob->Stringy Callable Callable Code Code Code->Any Code->Callable Block Block Block->Code Numeric Numeric Real Real Real->Numeric Int Int Int->Cool Int->Real Bool Bool Bool->Int Buf Buf Buf->Blob Exception Exception Exception->Any CX::Done CX::Done CX::Done->Exception X::Control X::Control CX::Done->X::Control CX::Emit CX::Emit CX::Emit->Exception CX::Emit->X::Control CX::Last CX::Last CX::Last->Exception CX::Last->X::Control CX::Next CX::Next CX::Next->Exception CX::Next->X::Control CX::Proceed CX::Proceed CX::Proceed->Exception CX::Proceed->X::Control CX::Redo CX::Redo CX::Redo->Exception CX::Redo->Exception CX::Redo->X::Control CX::Redo->X::Control CX::Return CX::Return CX::Return->Exception CX::Return->X::Control CX::Succeed CX::Succeed CX::Succeed->Exception CX::Succeed->X::Control CX::Take CX::Take CX::Take->Exception CX::Take->X::Control CX::Warn CX::Warn CX::Warn->Exception CX::Warn->X::Control CallFrame CallFrame CallFrame->Any Cancellation Cancellation Cancellation->Any Capture Capture Capture->Any Channel Channel Channel->Any Collation Collation Collation->Any CompUnit CompUnit CompUnit->Any CompUnit::PrecompilationRepository CompUnit::PrecompilationRepository CompUnit::Repository CompUnit::Repository CompUnit::Repository::Locally CompUnit::Repository::Locally CompUnit::Repository::FileSystem CompUnit::Repository::FileSystem CompUnit::Repository::FileSystem->Any CompUnit::Repository::FileSystem->CompUnit::Repository CompUnit::Repository::FileSystem->CompUnit::Repository::Locally CompUnit::Repository::Installable CompUnit::Repository::Installable CompUnit::Repository::Installation CompUnit::Repository::Installation CompUnit::Repository::Installation->Any CompUnit::Repository::Installation->CompUnit::Repository::Locally CompUnit::Repository::Installation->CompUnit::Repository::Installable Systemic Systemic Compiler Compiler Compiler->Any Compiler->Systemic Complex Complex Complex->Cool Complex->Numeric ComplexStr ComplexStr ComplexStr->Allomorph ComplexStr->Complex Scheduler Scheduler CurrentThreadScheduler CurrentThreadScheduler CurrentThreadScheduler->Any CurrentThreadScheduler->Scheduler Deprecation Deprecation Deprecation->Any Distribution Distribution Distribution::Locally Distribution::Locally Distribution::Locally->Distribution Distribution::Hash Distribution::Hash Distribution::Hash->Any Distribution::Hash->Distribution::Locally Distribution::Path Distribution::Path Distribution::Path->Any Distribution::Path->Distribution::Locally Distribution::Resource Distribution::Resource Distribution::Resource->Any Distro Distro Distro->Any Duration Duration Duration->Cool Duration->Real Encoding Encoding Encoding->Any Encoding::Registry Encoding::Registry Encoding::Registry->Any Endian Endian Endian->Int Enumeration Enumeration Nil Nil Nil->Cool Failure Failure Failure->Nil Rational Rational Rational->Real FatRat FatRat FatRat->Cool FatRat->Rational ForeignCode ForeignCode ForeignCode->Any ForeignCode->Callable Match Match Match->Cool Match->Capture Grammar Grammar Grammar->Match Map Map Map->Associative Map->Cool Map->Iterable Hash Hash Hash->Map PositionalBindFailover PositionalBindFailover Sequence Sequence Sequence->PositionalBindFailover HyperSeq HyperSeq HyperSeq->Any HyperSeq->Iterable HyperSeq->Sequence HyperWhatever HyperWhatever HyperWhatever->Any IO IO IO::Handle IO::Handle IO::Handle->Any IO::CatHandle IO::CatHandle IO::CatHandle->IO::Handle IO::ArgFiles IO::ArgFiles IO::ArgFiles->IO::CatHandle IO::Notification IO::Notification IO::Notification->Any IO::Notification::Change IO::Notification::Change IO::Notification::Change->Any IO::Path IO::Path IO::Path->Cool IO::Path->IO IO::Path::Cygwin IO::Path::Cygwin IO::Path::Cygwin->IO::Path IO::Path::Parts IO::Path::Parts IO::Path::Parts->Any IO::Path::Parts->Positional IO::Path::Parts->Associative IO::Path::Parts->Iterable IO::Path::QNX IO::Path::QNX IO::Path::QNX->IO::Path IO::Path::Unix IO::Path::Unix IO::Path::Unix->IO::Path IO::Path::Win32 IO::Path::Win32 IO::Path::Win32->IO::Path IO::Pipe IO::Pipe IO::Pipe->IO::Handle IO::Socket IO::Socket IO::Socket::Async IO::Socket::Async IO::Socket::Async->Any Tap Tap Tap->Any IO::Socket::Async::ListenSocket IO::Socket::Async::ListenSocket IO::Socket::Async::ListenSocket->Tap IO::Socket::INET IO::Socket::INET IO::Socket::INET->Any IO::Socket::INET->IO::Socket IO::Spec IO::Spec IO::Spec->Any IO::Spec::Unix IO::Spec::Unix IO::Spec::Unix->IO::Spec IO::Spec::Cygwin IO::Spec::Cygwin IO::Spec::Cygwin->IO::Spec::Unix IO::Spec::QNX IO::Spec::QNX IO::Spec::QNX->IO::Spec::Unix IO::Spec::Win32 IO::Spec::Win32 IO::Spec::Win32->IO::Spec::Unix IO::Special IO::Special IO::Special->Any IO::Special->IO Instant Instant Instant->Cool Instant->Real IntStr IntStr IntStr->Allomorph IntStr->Int Iterator Iterator Kernel Kernel Kernel->Any Label Label Label->Any Lock Lock Lock->Any Lock::Async Lock::Async Lock::Async->Any Lock::ConditionVariable Lock::ConditionVariable Lock::ConditionVariable->Any MOP MOP MOP->Any Routine Routine Routine->Block Macro Macro Macro->Routine Metamodel::Archetypes Metamodel::Archetypes Metamodel::Archetypes->Any Metamodel::AttributeContainer Metamodel::AttributeContainer Metamodel::BUILDPLAN Metamodel::BUILDPLAN Metamodel::BaseDispatcher Metamodel::BaseDispatcher Metamodel::BaseDispatcher->Any Metamodel::BaseType Metamodel::BaseType Metamodel::BoolificationProtocol Metamodel::BoolificationProtocol Metamodel::C3MRO Metamodel::C3MRO Metamodel::Naming Metamodel::Naming Metamodel::Documenting Metamodel::Documenting Metamodel::Versioning Metamodel::Versioning Metamodel::Stashing Metamodel::Stashing Metamodel::Finalization Metamodel::Finalization Metamodel::MethodContainer Metamodel::MethodContainer Metamodel::PrivateMethodContainer Metamodel::PrivateMethodContainer Metamodel::MultiMethodContainer Metamodel::MultiMethodContainer Metamodel::RoleContainer Metamodel::RoleContainer Metamodel::MultipleInheritance Metamodel::MultipleInheritance Metamodel::DefaultParent Metamodel::DefaultParent Metamodel::MROBasedMethodDispatch Metamodel::MROBasedMethodDispatch Metamodel::MROBasedTypeChecking Metamodel::MROBasedTypeChecking Metamodel::Trusting Metamodel::Trusting Metamodel::Mixins Metamodel::Mixins Metamodel::ClassHOW Metamodel::ClassHOW Metamodel::ClassHOW->Any Metamodel::ClassHOW->Metamodel::AttributeContainer Metamodel::ClassHOW->Metamodel::BUILDPLAN Metamodel::ClassHOW->Metamodel::BoolificationProtocol Metamodel::ClassHOW->Metamodel::C3MRO Metamodel::ClassHOW->Metamodel::Naming Metamodel::ClassHOW->Metamodel::Documenting Metamodel::ClassHOW->Metamodel::Versioning Metamodel::ClassHOW->Metamodel::Stashing Metamodel::ClassHOW->Metamodel::Finalization Metamodel::ClassHOW->Metamodel::MethodContainer Metamodel::ClassHOW->Metamodel::PrivateMethodContainer Metamodel::ClassHOW->Metamodel::MultiMethodContainer Metamodel::ClassHOW->Metamodel::RoleContainer Metamodel::ClassHOW->Metamodel::MultipleInheritance Metamodel::ClassHOW->Metamodel::DefaultParent Metamodel::ClassHOW->Metamodel::MROBasedMethodDispatch Metamodel::ClassHOW->Metamodel::MROBasedTypeChecking Metamodel::ClassHOW->Metamodel::Trusting Metamodel::ClassHOW->Metamodel::Mixins Metamodel::ConcreteRoleHOW Metamodel::ConcreteRoleHOW Metamodel::ConcreteRoleHOW->Any Metamodel::ConcreteRoleHOW->Metamodel::AttributeContainer Metamodel::ConcreteRoleHOW->Metamodel::Naming Metamodel::ConcreteRoleHOW->Metamodel::Versioning Metamodel::ConcreteRoleHOW->Metamodel::MethodContainer Metamodel::ConcreteRoleHOW->Metamodel::PrivateMethodContainer Metamodel::ConcreteRoleHOW->Metamodel::MultiMethodContainer Metamodel::ConcreteRoleHOW->Metamodel::RoleContainer Metamodel::ConcreteRoleHOW->Metamodel::MultipleInheritance Metamodel::ContainerDescriptor Metamodel::ContainerDescriptor Metamodel::ContainerDescriptor->Any Metamodel::RolePunning Metamodel::RolePunning Metamodel::TypePretense Metamodel::TypePretense Metamodel::CurriedRoleHOW Metamodel::CurriedRoleHOW Metamodel::CurriedRoleHOW->Any Metamodel::CurriedRoleHOW->Metamodel::RolePunning Metamodel::CurriedRoleHOW->Metamodel::TypePretense Metamodel::DefiniteHOW Metamodel::DefiniteHOW Metamodel::DefiniteHOW->Any Metamodel::DefiniteHOW->Metamodel::Documenting Metamodel::EnumHOW Metamodel::EnumHOW Metamodel::EnumHOW->Any Metamodel::EnumHOW->Metamodel::AttributeContainer Metamodel::EnumHOW->Metamodel::BUILDPLAN Metamodel::EnumHOW->Metamodel::BaseType Metamodel::EnumHOW->Metamodel::BoolificationProtocol Metamodel::EnumHOW->Metamodel::Naming Metamodel::EnumHOW->Metamodel::Stashing Metamodel::EnumHOW->Metamodel::MethodContainer Metamodel::EnumHOW->Metamodel::MultiMethodContainer Metamodel::EnumHOW->Metamodel::RoleContainer Metamodel::EnumHOW->Metamodel::MROBasedMethodDispatch Metamodel::EnumHOW->Metamodel::MROBasedTypeChecking Metamodel::EnumHOW->Metamodel::Mixins Metamodel::GenericHOW Metamodel::GenericHOW Metamodel::GenericHOW->Any Metamodel::GenericHOW->Metamodel::Naming Metamodel::GrammarHOW Metamodel::GrammarHOW Metamodel::GrammarHOW->Metamodel::DefaultParent Metamodel::GrammarHOW->Metamodel::ClassHOW Metamodel::MethodDelegation Metamodel::MethodDelegation Metamodel::MethodDispatcher Metamodel::MethodDispatcher Metamodel::MethodDispatcher->Metamodel::BaseDispatcher Metamodel::ModuleHOW Metamodel::ModuleHOW Metamodel::ModuleHOW->Any Metamodel::ModuleHOW->Metamodel::Naming Metamodel::ModuleHOW->Metamodel::Documenting Metamodel::ModuleHOW->Metamodel::Versioning Metamodel::ModuleHOW->Metamodel::Stashing Metamodel::ModuleHOW->Metamodel::TypePretense Metamodel::ModuleHOW->Metamodel::MethodDelegation Metamodel::MultiDispatcher Metamodel::MultiDispatcher Metamodel::MultiDispatcher->Metamodel::BaseDispatcher Metamodel::NativeHOW Metamodel::NativeHOW Metamodel::NativeHOW->Any Metamodel::NativeHOW->Metamodel::C3MRO Metamodel::NativeHOW->Metamodel::Naming Metamodel::NativeHOW->Metamodel::Documenting Metamodel::NativeHOW->Metamodel::Versioning Metamodel::NativeHOW->Metamodel::Stashing Metamodel::NativeHOW->Metamodel::MultipleInheritance Metamodel::NativeHOW->Metamodel::MROBasedMethodDispatch Metamodel::NativeHOW->Metamodel::MROBasedTypeChecking Metamodel::PackageHOW Metamodel::PackageHOW Metamodel::PackageHOW->Any Metamodel::PackageHOW->Metamodel::Naming Metamodel::PackageHOW->Metamodel::Documenting Metamodel::PackageHOW->Metamodel::Stashing Metamodel::PackageHOW->Metamodel::TypePretense Metamodel::PackageHOW->Metamodel::MethodDelegation Metamodel::ParametricRoleGroupHOW Metamodel::ParametricRoleGroupHOW Metamodel::ParametricRoleGroupHOW->Any Metamodel::ParametricRoleGroupHOW->Metamodel::BoolificationProtocol Metamodel::ParametricRoleGroupHOW->Metamodel::Naming Metamodel::ParametricRoleGroupHOW->Metamodel::Stashing Metamodel::ParametricRoleGroupHOW->Metamodel::RolePunning Metamodel::ParametricRoleGroupHOW->Metamodel::TypePretense Metamodel::ParametricRoleHOW Metamodel::ParametricRoleHOW Metamodel::ParametricRoleHOW->Any Metamodel::ParametricRoleHOW->Metamodel::AttributeContainer Metamodel::ParametricRoleHOW->Metamodel::Naming Metamodel::ParametricRoleHOW->Metamodel::Documenting Metamodel::ParametricRoleHOW->Metamodel::Versioning Metamodel::ParametricRoleHOW->Metamodel::Stashing Metamodel::ParametricRoleHOW->Metamodel::MethodContainer Metamodel::ParametricRoleHOW->Metamodel::PrivateMethodContainer Metamodel::ParametricRoleHOW->Metamodel::MultiMethodContainer Metamodel::ParametricRoleHOW->Metamodel::RoleContainer Metamodel::ParametricRoleHOW->Metamodel::MultipleInheritance Metamodel::ParametricRoleHOW->Metamodel::RolePunning Metamodel::ParametricRoleHOW->Metamodel::TypePretense Metamodel::Primitives Metamodel::Primitives Metamodel::Primitives->Any Metamodel::StaticLexPad Metamodel::StaticLexPad Metamodel::StaticLexPad->Any Metamodel::SubsetHOW Metamodel::SubsetHOW Metamodel::SubsetHOW->Any Metamodel::SubsetHOW->Metamodel::Naming Metamodel::SubsetHOW->Metamodel::Documenting Metamodel::WrapDispatcher Metamodel::WrapDispatcher Metamodel::WrapDispatcher->Metamodel::BaseDispatcher Method Method Method->Routine Mixy Mixy Mixy->Baggy Mix Mix Mix->Any Mix->Mixy MixHash MixHash MixHash->Any MixHash->Mixy Uni Uni Uni->Any Uni->Positional Uni->Stringy NFC NFC NFC->Uni NFD NFD NFD->Uni NFKC NFKC NFKC->Uni NFKD NFKD NFKD->Uni Num Num Num->Cool Num->Real NumStr NumStr NumStr->Allomorph NumStr->Num NumericEnumeration NumericEnumeration ObjAt ObjAt ObjAt->Any Order Order Order->Int Pair Pair Pair->Any Pair->Associative Parameter Parameter Parameter->Any Raku Raku Raku->Any Raku->Systemic Perl Perl Perl->Raku Pod::Block::Code Pod::Block::Code Pod::Block::Code->Pod::Block Pod::Block::Comment Pod::Block::Comment Pod::Block::Comment->Pod::Block Pod::Block::Declarator Pod::Block::Declarator Pod::Block::Declarator->Pod::Block Pod::Block::Named Pod::Block::Named Pod::Block::Named->Pod::Block Pod::Block::Para Pod::Block::Para Pod::Block::Para->Pod::Block Pod::Block::Table Pod::Block::Table Pod::Block::Table->Pod::Block Pod::Defn Pod::Defn Pod::Defn->Pod::Block Pod::FormattingCode Pod::FormattingCode Pod::FormattingCode->Pod::Block Pod::Heading Pod::Heading Pod::Heading->Pod::Block Pod::Item Pod::Item Pod::Item->Pod::Block PredictiveIterator PredictiveIterator PredictiveIterator->Iterator Proc Proc Proc->Any Proc::Async Proc::Async Proc::Async->Any Promise Promise Promise->Any PromiseStatus PromiseStatus PromiseStatus->Int Proxy Proxy Proxy->Any PseudoStash PseudoStash PseudoStash->Map RaceSeq RaceSeq RaceSeq->Any RaceSeq->Iterable RaceSeq->Sequence Range Range Range->Positional Range->Cool Range->Iterable Rat Rat Rat->Cool Rat->Rational RatStr RatStr RatStr->Allomorph RatStr->Rat Regex Regex Regex->Method Routine::WrapHandle Routine::WrapHandle Routine::WrapHandle->Any Scalar Scalar Scalar->Any Semaphore Semaphore Semaphore->Any Seq Seq Seq->Cool Seq->Iterable Seq->Sequence Setty Setty Setty->QuantHash Set Set Set->Any Set->Setty SetHash SetHash SetHash->Any SetHash->Setty Signal Signal Signal->Int Signature Signature Signature->Any Slip Slip Slip->List Stash Stash Stash->Hash StrDistance StrDistance StrDistance->Cool StringyEnumeration StringyEnumeration Sub Sub Sub->Routine Submethod Submethod Submethod->Routine Supplier Supplier Supplier->Any Supplier::Preserving Supplier::Preserving Supplier::Preserving->Supplier Supply Supply Supply->Any Telemetry Telemetry Telemetry->Any Telemetry::Instrument::Thread Telemetry::Instrument::Thread Telemetry::Instrument::Thread->Any Telemetry::Instrument::ThreadPool Telemetry::Instrument::ThreadPool Telemetry::Instrument::ThreadPool->Any Telemetry::Instrument::Usage Telemetry::Instrument::Usage Telemetry::Instrument::Usage->Any Telemetry::Period Telemetry::Period Telemetry::Period->Associative Telemetry::Period->Telemetry Telemetry::Sampler Telemetry::Sampler Telemetry::Sampler->Any Test Test Test->Any Thread Thread Thread->Any ThreadPoolScheduler ThreadPoolScheduler ThreadPoolScheduler->Any ThreadPoolScheduler->Scheduler UInt UInt UInt->Any VM VM VM->Any VM->Systemic ValueObjAt ValueObjAt ValueObjAt->ObjAt Variable Variable Variable->Any Version Version Version->Any Whatever Whatever Whatever->Any WhateverCode WhateverCode WhateverCode->Code atomicint atomicint atomicint->Int int int int->Int utf8 utf8 utf8->Any utf8->Blob

展开上面的图表