Reputation: 9600
When a proto and multis are defined in the same module, Type.^lookup('method').candidates
returns a list of all multi candidates. However, this appears not to work when the proto lives in a different file/module from the multis.
say Setty.^lookup('grab').candidates; # OUTPUT: ()
Is there any way to find the full list of multi candidates through Raku's introspection? Or is there no alternative to grepping through the source code? (I ask because having a full list of multi candidates applicable to a given proto would be helpful for documentation purposes.)
Upvotes: 7
Views: 106
Reputation: 29454
So far as multi
methods
go, it's not really to do with being in the same module or file at all. Consider these classes:
class Base {
proto method m(|) { * }
multi method m() { 1 }
}
class Derived is Base {
multi method m() { 2 }
}
Whenever we compose a class that contains multi methods, we need to attach them to a controlling proto
. In the case of Base
, this was explicitly written, so there's nothing to do other than to add the multi
candidate to its candidate list. Had we not written a proto
explicitly in Base
, however, then one with an empty candidate list would have been generated for us, with the same end result.
The process I just described is a bit of a simplification of what really happens, however. The steps are:
proto
already; if so, add the multi
to itproto
; if so, clone it (in tern cloning the candidate list) and add the multi
to that.proto
.And step 2 is really the answer to your question. If we do:
say "Base:";
.raku.say for Base.^lookup('m').candidates;
say "Derived:";
.raku.say for Derived.^lookup('m').candidates;
Then the output is:
Base:
multi method m (Base: *%_) { #`(Method|82762064) ... }
Derived:
multi method m (Base: ) { #`(Method|82762064) ... }
multi method m (Derived: ) { #`(Method|82762208) ... }
That is, the candidate list in Base
has one entry, and the candidate list in Derived
has the entry cloned from Base
as well as a new one.
Pretty much everything follows this principle: derived classes reference their base class (and the roles they do), but base classes (and roles) don't know about their descendants.
Upvotes: 6