Die Antwort von TL; DR JJ ist richtig, aber die Erklärung hat mich verwirrt. Ich betrachte das von Ihnen angezeigte Problem derzeit als Autovivifizierungsfehler / Fehler und / oder LTA-Fehlermeldung.
say my Any $Any; # (Any)
say my Hash $Hash; # (Hash)
say my Hash[Int] $Hash-Int; # (Hash[Int])
$Any<a> = 42; # OK
$Hash<a> = 42; # OK
$Hash-Int.new<a> = 42; # OK
$Hash-Int<a> = 42; # must be an object instance, not a type object
Imo das ist ein Fehler oder ziemlich nah an einem.
Ein Fehler / Problem tritt auch für Arrays im selben Szenario auf:
say my Any $Any; # (Any)
say my Array $Array; # (Array)
say my Array[Int] $Array-Int; # (Array[Int])
$Any[42] = 42; # OK
$Array[42] = 42; # OK
$Array-Int.new[42] = 42; # OK
$Array-Int[42] = 42; # Type check failed ... expected Array[Int] but got Array
Wenn es am besten als notabug angesehen wird, sollte möglicherweise die Fehlermeldung geändert werden. Obwohl ich JJ zustimme, dass die Fehlermeldung tatsächlich zutreffend ist (wenn Sie verstehen, wie Raku funktioniert und herausfinden, was los ist), denke ich, dass es dennoch eine LTA-Fehlermeldung ist, wenn wir Raku (do) nicht in dwim ändern.
Auf der packenden Hand ist mir nicht klar, wie man die Fehlermeldung am besten verbessern kann. Und jetzt haben wir dieses SO. (Siehe meinen Punkt dazu in Ist die ... Fehlermeldung LTA? in einer kürzlich von mir geschriebenen Antwort .)
Eine andere Lösung
Ich habe bereits das %
Siegel für die Hash-Variable ausprobiert , das funktioniert auch nicht.
JJ hat eine Lösung bereitgestellt, die mit einem Wert mit einem expliziten Wert initialisiert wird .new
. Dadurch wird jedoch die Einschränkung aus der Variablen entfernt. Um es zu behalten:
class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;
Im Idealfall constant
würde das nicht benötigt und vielleicht eines Tages auch nicht, aber ich denke, das Parsen von Merkmalen ist begrenzt.