brian d foy
brian d foy

Reputation: 132896

How can I know that I can call a Perl 6 method that with a particular signature?

In Perl 6, a multi-dispatch language, you can find out if there is a method that matches a name. If there is, you get a list of Method objects that match that name:

class ParentClass {
    multi method foo (Str $s) { ... }
    }

class ChildClass is ParentClass {
    multi method foo (Int $n) { ... }
    multi method foo (Rat $r) { ... }
    }

my $object = ChildClass.new;

for $object.can( 'foo' )
    .flatmap( *.candidates )
    .unique -> $candidate {
    put join "\t",
        $candidate.package.^name,
        $candidate.name,
        $candidate.signature.perl;
    };


ParentClass foo :(ParentClass $: Str $s, *%_)
ChildClass  foo :(ChildClass $: Int $n, *%_)
ChildClass  foo :(ChildClass $: Rat $r, *%_)

That's fine, but it's a lot of work. I'd much rather have something simpler, such as:

 $object.can( 'foo', $signature );

I can probably do a lot of work to make that possible, but am I missing something that's already there?

Upvotes: 3

Views: 142

Answers (1)

brian d foy
brian d foy

Reputation: 132896

As I hit submit on that question I had this idea, which still seems like too much work. The cando method can test a Capture (the inverse of a signature). I can grep those that match:

class ParentClass {
    multi method foo (Str $s) { ... }
    }

class ChildClass is ParentClass {
    multi method foo (Int $n) { ... }
    multi method foo (Rat $r) { ... }
    }

my $object = ChildClass.new;

# invocant is the first thing for method captures
my $capture = \( ChildClass, Str );

for $object.can( 'foo' )
    .flatmap( *.candidates )
    .grep( *.cando: $capture )
    -> $candidate {
    put join "\t",
        $candidate.package.^name,
        $candidate.name,
        $candidate.signature.perl;
    };

I'm not sure I like this answer though.

Upvotes: 1

Related Questions