ここでは、なぜスタブに関する警告がないのかと尋ねていると思います。実際、通常、スタブ化されたメソッドを実装する必要がありますが、それだけです。
役割がクラスにどのように構成されているかは、ここRakudoのソース($yada
基本的にはを意味します$is-stubbed
)で確認できます。
if $yada {
unless has_method($!target, $name, 0)
|| $!target.HOW.has_public_attribute($!target, $name) {
my @needed;
for @!roles {
for nqp::hllize($_.HOW.method_table($_)) -> $m {
if $m.key eq $name {
nqp::push(@needed, $_.HOW.name($_));
}
}
}
nqp::push(@stubs, nqp::hash('name', $name, 'needed', @needed, 'target', $!target));
}
}
したがって、ロジックが同じ名前のメソッドが存在するかどうかを確認するだけであることがわかります。apply()メソッドを拡張するか、RoleToClassApplier
クラスを完全に置き換えることで、このロジックを更新するモジュールを作成することは間違いなく可能です。しかし、それは難しいかもしれません。たとえば、次のことを考慮してください。
class Letter { }
class A is Letter { }
class B is Letter { }
role Foo {
method foo (Letter) { ... }
}
class Bar does Foo {
method foo (A) { 'a' }
method foo (B) { 'b' }
}
スタブメソッドが正しく実装されていると考える必要がありますか?しかし、後で誰かが言う可能性がclass C is Letter
あり、突然それは実装されていません。(もちろん、最良のロジックは少なくとも同一またはスーパータイプが必要であると言うことができますが、それは動的言語IMOに必要なものよりも制限的です)。
AFAICTはありません。作成中にロールで呼び出されるメソッドであり、クラスも参照します(実際にはで呼び出されるメソッドはありませんadd_method
)。そのため、ロール内に独自のチェックを記述する方法はありません。(しかし、私は間違っている可能性があり、レイフ、リズマットまたはjnthnが私を修正する可能性があります)。
この場合の私の推奨は、スタブする代わりに、単にdieステートメントを追加することです。
role L {
method do-l(Int $a, Int $b --> Int) {
die "SORRY! Classes implementing role L must support the signature (Int, Int)";
}
}
これはコンパイル時にそれをキャプチャしませんが、いずれかの時点で別のメソッドL
を呼び出す必要があるdo-l(Int, Int)
場合(たとえ構成クラスが他のシグネチャを実装していても)、それは呼び出され、エラーはかなり迅速にキャッチされます。
L.do-l
一致しない方法があり、どのような場合には、クラスメソッドは、その両方の拠点に、優先されるA
のは、do-l
呼び出す必要があります。追加Int
とReal
なりますReal
。