You are concerned with one of the things that are most difficult to understand about the delivery of several methods. The most important thing to understand is that each method signature has an implicit *%_ (aka slurpy hash) if it is not specified. This means that it will use any non-specific named parameters.
class A { method a() { dd %_ } # %_ exists even if not specifically specified } Aa(:foo) # {:foo}
Secondly, you need to understand that named parameters only act as tiebreaks. Therefore, if there are several candidates that have the same set of positional parameters, MMD will use the first one that works (given that all unexpected named parameters overlap %_ ):
class A { multi method a(:$foo) { say "foo" } multi method a(:$bar) { say "bar" } } Aa(:bar)
This seemingly unexpected result is due to the fact that:
- both candidates have the same number of positional parameters
- first candidate matches because
:$foo is optional - a
:bar - implicit *%_
To make it work more, as you expect, you need to put in candidates who need to be tied to the order you want them to shoot and make any named parameters mandatory:
class A { multi method a(:$foo!) { say "foo" } multi method a(:$bar!) { say "bar" } } Aa(:bar)
If you have candidates that accept multiple named parameters, they quickly become quite complex, and you might be better off just using a method that uses the introspection %_ :
class A { method a() { if %_<foo> { say "foo" } elsif %_<bar> { say "bar" } else { die "None of the signatures matched" } } } Aa(:bar)
Hope this makes it easier :-)
Elizabeth Mattijsen
source share