Hello all.

I have some questions about how Roles will behave in certain instances, and when/where/what $?ROLE should be bound too.

1) Given this example, where 'bar' is a method stub (no implementation)

role Foo {
    method bar { ... }
}

Should the eventually implemented method still have a binding for $? ROLE?

2) When a Role itself has subroles, which are composed together and consumed by the parent Role, how is $?ROLE bound? is it the top-most Role which it is bound too? or is it bound to the Role it originally came from? Here is an example:

role Foo {
    method foo { $?ROLE }
}

role Bar {
    method bar { $?ROLE }
}

role FooBar does Foo does Bar {}

Given this code, does FooBar::foo return FooBar? or Foo? And what about FooBar::bar?

This also brings up another question.

3) Using the Roles above, what will this code do?

class MyClass does FooBar {
    method foo {
        $?SELF.FooBar::foo();
    }
}

Since Roles are flattened, I would think it is reasonable to assume that FooBar::foo exists. However, it does not exists in the concrete in-the-namespace-stash sense. Should fully qualified access to Role methods be mediated by some kind of proxy? Should it actually query a composite Role of some kind?

The easy way I think, is to say the above code will fail since FooBar::foo does not exist. However consider for a moment how Role composition works, and how flattening sort of "equalizes" all the methods and makes ordering unimportant. These qualities are what give Roles such great compositional power, and reduce the complexities/ issues usually associated with mix-ins and multiple inheritance. If you force the user to see the entire Role hierarchy, and not just the topmost Role, are you loosing some of that compositional power?

And lastly ...

4) If a Role has a method stub, you are in effect creating a contract with any class which consumes that Role. The class must implement that method. However, what happens if the class consumes another Role which implements that method. Do they still conflict? or does the second Role's version fufill the first Role's contract?

Here is a quick code example:

role Foo {
    method foo { ... }
}

role Bar {
    method foo { "Hello World".say }
}

class FooBar does Foo does Bar {}

Does this work? Does Bar fufill Foo's implied contract? Or is an exception thrown here?

Thanks,

Stevan

Reply via email to