On Thu, Oct 27, 2005 at 22:19:16 -0400, Stevan Little wrote: > Hello all, > > I have a question about method conflict resolution works for roles, and I > cannot seem to find this in any > of the Apoc/Syn documents. > > Here is the basic issue: > > role Foo { > method foo { ... } > method bar { ... } # we will use this later :) > } > > role Bar { > method foo { ... } > } > > role FooBar { > does Foo; > does Bar; > } > > Now, at this point we have a method conflict in suspension since (according > to A/S-12) method conflicts do > not throw an error until a role is composed into a class. This means that > when I do this: > > class MyClass does FooBar {} > > an exception is thrown. Unless of course MyClass has a &foo method, which > will disambiguate the conflict. > My question then is, can FooBar (the role) disambiguate the &foo conflict?
IMHO yes, but it doesn't have too. It should be able to leave it to the class to decide. > role FooBar { > does Foo; > does Bar; > method foo { ... } > } > > Now, on the surface this seems obvious, of course the FooBar role should be > able to disambiguate. However, > when we expand the example other issues show up. > > role Baz { > does Foo; > } > > class MyClass2 does FooBar does Baz {} # Will this die? <splice> > But thats not all, we have a potential problem with &foo again. Baz will > provide &foo from Foo, but FooBar > will provide it's own &foo (which we used to disambiguate). So our > disambiguation is not ambiguated > again. </splice> yes, since the methods are coming from different context, and they may have different meanings. While FooBar::foo resolves the conflict from the assimilation of Foo::foo and Bar::foo, it does it only within FooBar. If, OTOH we have a diamond inheritence: role A { method foo { ... } } role B does A {}; role C does A {}; class D does A does B { }; I'm not sure we need to resolve the conflict. > Now, since MyClass2 actually does Foo twice, does that mean &bar creates a > conflcit? Since &bar would be > found through FooBar and Baz. I would think the answer here would be no, and > that we would build some > kind of unique list of roles so as to avoid repeated consumption like this. No conflict - an assimilated role is identicle to itself even through different paths since it doesn't get access to private or protected member data of it's consuming roles. If, on the other hand, we have role X trusts Foo does Foo { has $:foo; } role Y trusts Foo does Foo { has $:foo; } role Foo { method foo { $:foo++; } } class C does X does Y { } there is a conflict, because Foo is reaching into either X's private member $:foo or Y's private member $:foo (btw, they should never conflict with each other). The moment a method will have behavior that is different in two different role consumptions it will be conflicting, but this will only happen to a method from the same class if it has some private symbols resolved at role composition time using class friendship. I think it is ambiguous, s > A (deceptively) simple solution to this is that MyClass2 needs to > disambiguate. But this means that our > roles are not really black boxes anymore. In order to properly disambiguate > this we need to know where > all the &foo methods are coming from (Foo, Bar and FooBar), and potentially > what is inside these &foo > methods (especially in the case of FooBar since it is attempting to > disambiguate, it's behavior could be > very specific). It probably would also become important to know what other > methods &foo interacts with > since we potentially have 3 different expected versions of &foo. method foo is Foo::foo; or method foo (*$a) { ./Foo::foo(*$a) } or &foo ::= &Foo::foo; > In the end, we will have probably looked inside every method defined in Foo, > Bar, FooBar and Baz in order > to properly write MyClass2. IMHO, this is sort of defeating the usefulness > of roles at this point. I disagree - you have to know what a role is actually giving you to exploit it. Too much black boxing makes your programming language seem like a Kafka story. > So what do you all think?? Role method conflicts should only be dealt with if the user knows what the roles are actually doing anyway. This will probably be familiar code, and if not it warrants familiarity. I don't think we can let the user use library code without being aware of the library code internals at all. Abstraction that works like this is usually either crippled or useless. 90% of the time you don't want to know, but there are exceptions. -- () Yuval Kogman <[EMAIL PROTECTED]> 0xEBD27418 perl hacker & /\ kung foo master: /me sushi-spin-kicks : neeyah!!!!!!!!!!!!!!!!!!!!
pgpmmr3g6z6ZK.pgp
Description: PGP signature