11
votes

I am trying to do some OOP with Perl6 and am having a little trouble with roles. I am trying to use them in a similar way to a Java interface, where I would just have method signatures that must be implemented by any class that does the role. I am using stubbed methods with typed parameters and return.

I am noticing that the type signatures are not being enforced though, only the name of the method.

Example script:

#!/usr/bin/env perl6
use v6;

role MyRole {
    method intAdder( Int $a, Int $b --> Int ) { ... }
}

# this does the role and the method signature matches
class MyClass1 does MyRole {
    method intAdder( Int $a, Int $b --> Int ) { return $a+$b }
}

# this does the role and the method signature does NOT match
# why is this allowed?
class MyClass2 does MyRole {
    method intAdder( Str $a --> Str ) { return "Hello, $a." }
}

# this does the role and the method name does not match and gives an error as expected:
# Method 'intAdder' must be implemented by MyClass3 because it is required by roles: MyRole.
#
# class MyClass3 does MyRole {
#     method adder( Int $a, Int $b --> Int ) { return $a+$b }
# }

sub MAIN() {
    my $object1 = MyClass1.new;
    my $object2 = MyClass2.new;
    say $object1.intAdder: 40, 2;
    say $object2.intAdder: 'world';
}

# output:
# 42
# Hello, world.

I have read through the Object orientation page in the official docs and can't find a way to do what I want... I am also trying to apply a Java way of thinking about OOP and typing and maybe there is a different, more Perl6ish way to do what I want...

1
If this ends up generating a bug report, please consider also referencing github.com/rakudo/rakudo/issues/2146raiph

1 Answers

7
votes

If you declare a method using multi method in the role, then P6 enforces that there's a multi method in the consumer with a matching signature. (It allows other signatures too.)

If you omit the multi in the role, P6 does not enforce the signature, only that a method with the matching name is declared in a consumer.

I don't know why it works this way.

2020 update See my commentary beginning "I think the design intent was to support two notions of polymorphic composition" in my answer to SO "Signature restriction in roles in raku". (The 2020 question is a dupe of this one but I didn't remember this one, and unfortunately didn't find it when I searched either.)