Suponho que aqui você esteja perguntando por que não há nenhum aviso com relação à punição. De fato, normalmente um método stubbed deve ser implementado - mas é isso.
Você pode ver como os papéis são compostos em classe aqui na fonte de Rakudo ( $yada
basicamente significa $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));
}
}
Então você pode ver que a lógica é apenas para ver se existe um método com o mesmo nome. Definitivamente, é possível escrever um módulo que atualize essa lógica aumentando o método apply () ou substituindo completamente a RoleToClassApplier
classe. No entanto, pode ser difícil. Por exemplo, considere:
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' }
}
Devemos considerar o método stubbed implementado corretamente? Mas alguém poderia dizer mais tarde class C is Letter
e de repente não foi implementado. (Obviamente, poderíamos dizer que a melhor lógica seria exigir, no mínimo, o idêntico ou o supertipo, mas isso é mais restritivo do que o necessário para linguagens dinâmicas, IMO).
Não existe, AFAICT, um método chamado de funções durante a composição que também faz referência à classe (na verdade, não existe nenhum método chamado add_method
), portanto não há como escrever sua própria verificação dentro da função. (mas eu posso estar errado, talvez raiph, lizmat ou jnthn possam me corrigir).
Minha recomendação nesse caso seria, em vez de removê-la, simplesmente adicionar uma declaração de dado:
role L {
method do-l(Int $a, Int $b --> Int) {
die "SORRY! Classes implementing role L must support the signature (Int, Int)";
}
}
Isso não o capturará na compilação, mas se a qualquer momento outro método L
precisar chamar do-l(Int, Int)
- mesmo que a classe de composição implemente outras assinaturas -, ela será chamada e o erro detectado rapidamente.
L.do-l
tem um método que não corresponde, e em qualquer caso, o método de classe tem precedência, então em ambos bases,A
'sdo-l
deve ser chamado. A adição de umInt
e aReal
será aReal
.