Существует способ, которым вы можете использовать FALLBACK
для более чем одной операции, при условии, что они в некотором роде различаются.
Проверяя некоторые свойства объекта:
class Foo {
# this could be set as part of `new`/`BUILD`
has %!special = ( "peter" => 42 );
multi method FALLBACK ( $name where (%!special{$name}:exists) ) {
%!special{$name}
}
multi method FALLBACK ( $other ) {
$other.tc
}
}
with Foo.new {
say .paul; # Paul
say .peter; # 42
}
У этого есть потенциальная проблема действия на расстоянии.
С другим числом или типами аргументов:
class Bar {
multi method FALLBACK ( Str:D $name ) {
$name.tc
}
multi method FALLBACK ( Str:D $name, Real:D $number ) {
$name.tc, 1 / $number
}
multi method FALLBACK ( Str:D $name, Str:D $other ) {
$name.tc, $other.uc
}
}
with Bar.new {
say .paul; # Paul
say .peter(42); # Peter, 0.02381
say .peter('Paul'); # Peter, PAUL
}
Вы можете использовать .[…]
для аргумента Int.
class Baz {
method AT-POS ( $arg ) { say "Baz[$arg]" }
}
Baz.new[42,32]; # Baz[42]
# Baz[32]
Встроенный postcircumfix:« [ ] »
приводит аргументы к Int, но вы можете добавить новый вмикс.
(При этом есть несколько предостережений.)
multi sub postcircumfix:<[ ]> ( Baz:D $b, $a ) is export {
# $b.AT-POS( $a )
$b.some-method( $a )
}
Вы можете использовать .<…>
для Strs, разделенных пробелами, или .{…}
для произвольных значений.
class Other {
multi method AT-KEY ( Str:D $name ){
$name.tc
}
multi method AT-KEY ( Real:D $number ){
1 / $number
}
}
with Other.new {
say $_<peter>; # Peter
say $_.<paul>; # Paul
say .<peter paul>; # Peter Paul
# note that AT-Key got called twice
say $_{42,'peter'}; # 0.02381, Peter
# note that AT-Key got called twice
}
Вы можете сделать так, чтобы ваш объект вызывался.
class Fubar {
multi method CALL-ME ( Str:D $name ){
$name.tc
}
multi method CALL-ME ( Real:D $number ){
1 / $number
}
multi method CALL-ME ( +@args ){
@args.map: {self.CALL-ME($_)}
}
}
with Fubar.new {
say $_('peter'); # Peter
say $_(42); # 0.02381
# this calls the +@args one
say $_('paul',32); # Paul, 0.03125
}
Вы должны действительно подумать о своем API, прежде чем делать что-либо из этого.