I have a class that does a role that does another role. A method from the class can access an attribute in the top level role:
role A {
has $.x
}
role B does A {
}
class C does B {
method this() { say $!x }
}
C.new(:x(1)).this;
That works fine and says 1 like I think it should.
But I have a number of classes that all do role B, that I want to share the method this(), so I move it up into role B:
role A {
has $.x
}
role B does A {
method this() { $!x }
}
class C does B {}
C.new(:x(1)).this;
That won't even compile: SORRY Attribute $!x not declared in role B
.
Can a role not see attributes in a role it includes?
Mutually exclusive roles are roles such that a user can be assigned to only one role in the set.
The role attribute describes the role of an element in programs that can make use of it, such as screen readers or magnifiers. Screen Readers will read this element as “button” instead of “link”.
Role-based authorization enables customer management of users and their roles independently from Payment Feature Services. Role-based authorization has a user registry that is not part of Payment Feature Services. This authorization is optional and does not replace the current model.
2. Hierarchical RBAC, as the name suggests, implements a hierarchy within the role structure. This hierarchy establishes the relationships between roles. Users with senior roles acquire permissions of all junior roles, which are assigned to their subordinates.
Doing this requires the introduction of a private method in the first role and access through that:
role A {
has $.x;
method !x() { $!x }
}
role B does A {
method this() { self!x }
}
class C does B {}
say C.new(:x(1)).this; # 1
The reason the original code doesn't work - and isn't trivial to make it work - is that roles are generic and potentially overloaded with different sets of type parameters, so the mention of a role is itself generic. Therefore, in general, the does A
does not identify a specific target role; there could be multiple of them, and they could have different attributes. It's not until the point that we compose the role into a class that we finally identify the concrete set of roles being composed.
However, attribute accesses are a kind of variable access, and so checked at the point we are compiling the role. In the final class, this isn't so much of a problem, since we are at that point choosing all the concrete roles we'll use; this is why it can easily work there. For the role
case, we couldn't really check them until the point of composition into a final class, which could be in a separate compilation unit altogether. This is likely a solvable problem, and a future Perl 6 language version could specify a way for this to work. For now, it conservatively does not.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With