Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can roles access included role attributes?

Tags:

raku

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?

like image 900
Curt Tilmes Avatar asked Jan 12 '19 14:01

Curt Tilmes


People also ask

Is a role that user can only be assigned to a particular role if it is already assigned to some other specified role?

Mutually exclusive roles are roles such that a user can be assigned to only one role in the set.

What are attribute roles?

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”.

What is role-based Authorisation?

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.

Is RBAC hierarchical?

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.


1 Answers

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.

like image 172
Jonathan Worthington Avatar answered Oct 11 '22 11:10

Jonathan Worthington