Consider this example where a subclass has a multi method with no signature and one with a slurpy parameter:
class Foo {
multi method do-it { put "Default" }
multi method do-it ( Int $n ) { put "Int method" }
multi method do-it ( Str $s ) { put "Str method" }
multi method do-it ( Rat $r ) { put "Rat method" }
}
class Bar is Foo {
multi method do-it { put "Bar method" }
multi method do-it (*@a) { put "Bar slurpy method" }
}
Foo.new.do-it: 1;
Foo.new.do-it: 'Perl 6';
Foo.new.do-it: <1/137>;
Foo.new.do-it;
put '-' x 10;
Bar.new.do-it: 1;
Bar.new.do-it: 'Perl 6';
Bar.new.do-it: <1/137>;
Bar.new.do-it: 5+3i;
Bar.new.do-it;
How is the method lookup structured? I'm looking more for a way to explain it and specifically not complaining about it.
Int method
Str method
Rat method
Default
----------
Int method
Str method
Rat method
Bar slurpy method
Bar method
There's a call to Bar's do-it with 1 for instance. Some reasonable people might think that it looks for a matching signature in Bar first and that slurpy would never let anything get past it. Yet, the call finds the right multi in the inheritance chain.
Does Bar already know all the signatures? Does it search or is all of that stuff already resolved when it is composed?
And, is there a way to find out at run time which class provided the method? Maybe with some call into HOW? This would be a handy debugging tool when I have a multi I've incorrectly specified and is being handled elsewhere.