为什么 Duration.new 使用 Int 而不是 Rat?

Why does Duration.new work with Int but not Rat?

对于 Duration,为什么我需要手动将 Rat 强制转换为 Real,而不是 Int?

这是基于 MoarVM 2020.01.1 版构建的 Rakudo 2020.01 版 实施 Perl 6.d。在 OSX.

say $v.WHAT; #(Int)
$v = Duration.new( $v );
say $v;     #20 

my $w = 20.0;
say $w.WHAT; #(Rat)
$w = Duration.new( $w.Real );
say $w;     #20 

my $x = 20.0;
say $x.WHAT; #(Rat)
$x = Duration.new( $x );
say $x;     #hangs

这是一个错误。 https://github.com/rakudo/rakudo/commit/f70d95e299.

已修复

它对 Rat 的行为不同于任何其他类型的原因是 Rat 案例被优化为不必进行任何强制转换,因此不需要检查结果胁迫。在那种情况下,该值被直接放入新的 Duration 对象中。但是,它没有去容器化就这样做了,因此 Duration 对象实际上会引用您示例中的变量 $x 。这通常都很好,但是 .gist 逻辑以某种方式创建了一个无限循环,试图创建 Duration 的表示,因为这种自引用。必须承认我并没有真正研究它到底是在哪里进入循环的。

无论如何,通过确保值在 Duration 对象内部被去容器化,问题就会消失,因为它不能再自引用了。