割り当て演算子を使用する場合、「メソッド 'ASSIGN-KEY'の呼び出し元はオブジェクトインスタンスでなければなりません」


10

入力されたキーによるハッシュ…

use v6;
class Foo {}
my Hash[Foo, Foo] $MAP;

my $f1 = Foo.new;
my $f2 = Foo.new;

$MAP{$f1} = $f2;

エラーを生成します:

メソッド 'ASSIGN-KEY'の呼び出し元は、タイプ 'Hash [Foo、Foo]'のタイプオブジェクトではなく、タイプ 'Hash [Foo、Foo]'のオブジェクトインスタンスでなければなりません。「.new」を忘れましたか?

私はそれが誤解を招くと思います。実際のエラーは何ですか?代わりに何を書かなければなりませんか?

私はすでに%ハッシュ変数のシギルを試しましたが、それもうまくいきません。


$ MAPはクラスであるということです。OTOMH、それは役割だと思います。それをインスタンス化する必要があります。しかし、確認させてください。
jjmerelo

回答:


7

あなたがそれを定義した方法で、$MAP実際には役割です。あなたはそれをインスタンス化する必要があります(実際には、しゃれます):

class Foo {}
my Hash[Foo, Foo] $MAP;

my $map = $MAP.new;

my $f1 = Foo.new;
my $f2 = Foo.new;

$map{$f1} = $f2;
say $map;

ここでの死んだ景品は、クラスがパラメータ化できないこと、役割はそうであることでした。

また:

say $MAP.DEFINITE; # False
say $map.DEFINITE; # True

しかし、実際には、ここで行うように、エラーメッセージはを使用するための提案を含めてかなり有益でし.newた。

以下に短縮できます。

class Foo {}
my %map = Hash[Foo, Foo].new ;
%map{Foo.new} = Foo.new;
%map.say;

定義からパンニングを行うことにより、$ MAP中間クラスは必要なくなります。


6

TL; DR JJの答えは正しいですが、説明では混乱しました。私は現在、あなたが示した問題をautovivificationエラー/バグまたはLTAエラーメッセージとして表示しています。

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

イモこれはバグかかなり近いです。

同じシナリオで、バグ/問題が配列にも適用されます。

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

notabugを検討するのが最善の場合は、おそらくエラーメッセージを変更する必要があります。エラーメッセージが実際に適切であるとJJに同意していますが(rakuの仕組みを理解し、何が起こっているのかを理解している場合)、それでもraku(do)をdwimに変更しない場合は、LTAエラーメッセージであると思います。

握る側では、エラーメッセージをどのように改善すればよいかは明らかではありません。そして今、このSOがあります。(その中程度の私のポイントCF ?...エラーメッセージLTAです私が書いた最近の答え。)

別の解決策

私はすでに%ハッシュ変数のシギルを試しましたが、それもうまくいきません。

JJは、明示的なを持つ値で初期化するソリューションを提供しています.new。しかし、それによって変数から制約が削除されます。それを保持するには:

class Foo {}
constant FooFoo = Hash[Foo:D,Foo:D];
my %foo is FooFoo;
%foo{Foo.new} = Foo.new;

理想的にconstantはそれは必要ないでしょう、そしておそらくいつかそれは必要ないでしょうが、私は特性解析が制限されていると思います。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.