Hash z wpisywanymi klawiszami…
use v6;
class Foo {}
my Hash[Foo, Foo] $MAP;
my $f1 = Foo.new;
my $f2 = Foo.new;
$MAP{$f1} = $f2;
produkuje błąd:
Wywoływacz metody „ASSIGN-KEY” musi być instancją obiektu typu „Hash [Foo, Foo]”, a nie obiektem typu „Hash [Foo, Foo]”. Czy zapomniałeś „.new”?
Uważam to za mylące; jaki jest prawdziwy błąd i co mam zamiast tego napisać?
Próbowałem już %
sigil dla zmiennej hash, to też nie działa.
Odpowiedzi:
Sposób, w jaki go zdefiniowałeś,
$MAP
jest właściwie rolą. Musisz utworzyć instancję (właściwie pun ):Martwa gratka polegała na tym, że klas nie można sparametryzować , role pełnią.
Również:
Ale tak naprawdę komunikat o błędzie był dość pouczający, łącznie z sugestią użycia
.new
, tak jak tutaj.Możemy go skrócić do:
Wykonując wykreślanie z definicji, nie potrzebujemy klasy pośredniej $ MAP.
źródło
TL; DR JJ odpowiedź jest słuszna, ale wyjaśnienie mnie pomieszało. Obecnie widzę problem, który pokazałeś jako komunikat o błędzie / błędzie automatycznej weryfikacji i / lub komunikat o błędzie LTA.
Imo, to jest błąd lub bardzo blisko jednego.
Błąd / problem dotyczy również tablic w tym samym scenariuszu:
Jeśli najlepiej to uznać za notabug, być może komunikat o błędzie powinien zostać zmieniony. Chociaż zgadzam się z JJ, że komunikat o błędzie jest rzeczywiście na miejscu (kiedy zrozumiesz, jak działa raku i zorientujesz się, co się dzieje), myślę, że mimo to jest to komunikat o błędzie LTA, jeśli nie zmienimy raku (do) na dwim.
Jeśli chodzi o chwytającą rękę, nie jest dla mnie oczywiste, jak najlepiej poprawić komunikat o błędzie. A teraz mamy to SO. (por. moje zdanie na ten temat w Czy komunikat o błędzie LTA? w ostatniej odpowiedzi, którą napisałem .)
Inne rozwiązanie
JJ dostarczył rozwiązanie, które inicjuje się wartością jawną
.new
. Ale to usuwa ograniczenie ze zmiennej. Aby to zachować:Idealnie
constant
nie byłoby to potrzebne, a może kiedyś nie będzie, ale myślę, że analiza cech jest ograniczona.źródło