my %f;
for $*HOME.dir() -> $file {
my $filename = $file.basename;
%f{$filename}.push: $file, rand;
}
my $p = %f.first;
say $p.^name;
say "{$p.values.^name} has {$p.values.elems} elements";
say "{$p.values[0].^name} has {$p.values[0].elems} elements";
say '';
say $*RAKU;
say $*DISTRO;
say $*KERNEL;
say $*VM;
输出:
Pair
Seq has 1 elements
Array has 2 elements
Raku (6.d)
macos (13.2.1)
darwin
moar (2023.02)
为什么
.values
的%f
是Seq
的Array
,而不是简单的Array
?
如您的
say $p.^name
线所示,$p
是一个 Pair
。这个Pair
的值是一个Array
;如果你打电话给$p.value
,你会得到那个Array
。但是$p.values
(带有“s”)返回所有$p
值的序列——也就是说,Seq
包含一个Array
.
为什么 %f 的 .values 是 Array 的 Seq
(我不确定这是一个错字,但请注意,您在
.values
的 .first
元素上调用了 %f
,而不是在 %f
本身上调用。在所有 .values
上调用 %f
也会给你一个 Seq
的 Array
s,但有更多的元素(%f
中的每个条目一个。另请注意,%f
(Hash
)未排序,因此 .first
没有' t 返回一个一致的元素——这是很少你想要的。)
为什么
的.values
是%f
的Seq
,而不是简单的Array
?Array
首先,正如@codesections 指出的那样,它不是
%f
,它是%f
中的单个元素(“第一个”元素,具有误导性,但这是一个转移注意力的问题)。
所以这是
.values
的Pair
。
Pair.values
的文档说:
multi method values(Pair:D: --> List:D)
返回包含调用者值的
。List
医生说它应该是一个
List
(既不是Seq
也不是Array
)。
糟糕
.values
中的当前
main/src/core.c/Pair.pm6
方法声明是:
multi method values(Pair:D:) {
Seq.new(Rakudo::Iterator.OneValue($!value))
}
这就是为什么你得到一个
Seq
.
但是你应该吗?为什么实际结果与文档不符?需要修复什么?
一种可能是文档一直是错误的。 Git blame 显示它是在 2016 年中期编写的。文档曾经是正确的但 Rakudo 改变了吗?
我加入了自助
#whateverable
IRC机器人频道(使用kiwiirc),然后输入:
c: say (:a).values ~~ List
commitable6
,Raku IRC 机器人 家族之一,以测试在 Rakudo 编译器版本上运行该代码的结果。
几分钟后我得到一份报告显示Rakudo确实返回了一个
List
——直到2017.08.
2017.08发生了什么?
main/src/core.c/Pair.pm6
的 git blame 报告显示 a Liz commit:
简化 Pair 上的标准 Seq 方法
- 添加专用的.iterator
- 确保 .keys/kv/values/pairs/antipairs 产生一个 Seq 而不是列表,就像他们在任何其他对象上所做的那样。
这就是为什么 Rakudo 改变了,所以
Pair.values
返回一个 Seq
.
我刚刚查了一下,
Pairs.kv
的文档也是错误的,我认为最好假设 .keys/kv/values/pairs/antipairs 的文档也都是错误的。
我希望在这个周末写下我的结论,但会发表我目前的结论。