I'm trying to create a callable variable for a class method.
class Person {
method walk(Str $direction) {
say "Walking $direction";
}
}
I can create a callable variable for the method 'walk' that works as expected.
my $person = Person.new;
my $callable = $person.^find_method('walk');
$person.$callable('up'); # OUTPUT: "Walking up"
Now I want to create a callable that will call method 'walk' with the parameter 'up'.
my $callable = $person.^find_method('walk').assuming('up');
$person.$callable();
# Type check failed in binding to parameter '$direction'; expected Str but got Person (Person.new)
# in sub __PRIMED_ANON at EVAL_7 line 1
# in block <unit> at <unknown file> line 1
$person.$callable (without the parentheses) gives the same error
I tried calling it 'directly', but got a different error.
$person.^find_method('walk')('up')
# Too few positionals passed; expected 2 arguments but got 1
# in method walk at <unknown file> line 2
# in block <unit> at <unknown file> line 1
Is this possible?
Yes, this is possible. The missing piece is that methods implicitly receive their invocant as their first positional parameter (that is, the signature of
Person'swalkmethod is reallymethod walk(Person: Str $direction)) and receiveselfas their first positional argument.This means that you need to use
assumingto supply the second positional argument instead of the first. Here's how that'd look:As another option, instead of using
*for the first positional parameter, you could use$person; if you did that,$callable()would return"Walking up"without needing to be invoked on aPerson.