https://github.com/rakudo/rakudo/issues/2657 - looks like an outright bug,
to me.

I don't know about "the big picture" but you hit a
not-explicitly-documented case.

Referring to
https://docs.perl6.org/language/objects#index-entry-declarator_role-Roles -

*When a role is applied to a class, the methods of that role are copied
into the class. If multiple roles are applied to the same class, conflicts
(e.g. attributes or non-multi methods of the same name) cause a
compile-time error, which can be solved by providing a method of the same
name in the class.*

That page continues on to an example which works- I added a couple lines to
print output-

use v6.c;

role Bull-Like {
    has Bool $.castrated = False;
    method steer {
        # Turn your bull into a steer
        $!castrated = True;
        return self;
    }
}
role Steerable {
    has Real $.direction;
    method steer(Real $d = 0) {
        $!direction += $d;
    }
}

# Try changing 'class' to 'role' on the next line
class Taurus does Bull-Like does Steerable {
    method steer($direction?) {
        self.Steerable::steer($direction)
    }
}

my $t=Taurus.new;
say $t.steer(3.3); # Says 3.3 when Taurus is a class, dies when a role.
say $t.steer(1.1); # Says 4.4 (if it gets this far)

That section explicitly discusses what happens when multiple roles with the
same name are applied to a class, and how the class is to resolve it. But
it never mentions applying roles with conflicting names to another role.

It appears that the Rakudo implementation has the same blind spot as the
Perl6 documentation.

I'd like it if roles disambiguated same-name application just as classes
did. Which means, the role they are applied to must have a role with the
same name explicitly calling the methods it wants- compile time error
otherwise. Roles would never participate in MRO, because their "flatness"
part of their attractiveness - there's no guessing which role is providing
a method, any potential name clash is averted by requiring calling out the
role or class providing the desired semantics.

Through that lens, my thoughts on
https://github.com/rakudo/rakudo/issues/2282 - ought to run without error
https://github.com/rakudo/rakudo/issues/2496 - my edits/comments
role  X        { method f { say "f" } }
role  Y does X { method g { say "g" } }
class C does Y {}

C.new.Y::g;  # works
C.new.Y::f;  # works
C.new.X::f;  # LTA error. But with roles doing "flat" copying don't have an
expectation that C knows the name "X",
# I only expect that C can call method f which it got from Y, and that did
work.

-y

Reply via email to