Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

raku

For a Duration, why do I need to coerce a Rat to a Real by hand, but not an Int?

This is Rakudo version 2020.01 built on MoarVM version 2020.01.1 implementing Perl 6.d. On 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
like image 535
p6steve Avatar asked Apr 10 '20 10:04

p6steve


1 Answers

This is a bug. Which has been fixed with https://github.com/rakudo/rakudo/commit/f70d95e299.

The reason it acted differently for Rat than for any other type, is that the Rat case was optimized to not have to do any coercion, and thus not needed to check the result of the coercion. In that case, the value was put directly into the new Duration object. However, it did so without de-containerizing, so the Duration object would actually be referencing the variable $x from your example. This is all fine generally, but the .gist logic somehow created an infinite loop trying to create a representation of the Duration because of this self-reference. Must admit I didn't really looked into where it exactly got into a loop.

Anyways, by making sure the value gets decontainerized inside the Duration object, the problem goes away as then it cannot be self-referencing anymore.

like image 182
Elizabeth Mattijsen Avatar answered Nov 10 '22 20:11

Elizabeth Mattijsen