[Pharo-project] Flattening traits
Hello, I am trying to load Ring into GemStone. As Ring uses traits, the first thing I did was flatten the traits. Based on a thread on this mailing list from June 2011 (Elliot flattening the traits in Fuel) I used Behavior>flattenDownAllTraits. One thing I noticed is that, while this method successfully flattens the instance methods of the trait, the class methods appear to be just removed. I was able to fix this by changing method Behavior>>flattenDown. Before this method was implemented as: flattenDown: aTrait | selectors | [self hasTraitComposition and: [self traitComposition allTraits includes: aTrait]] assert. selectors := (self traitComposition transformationOfTrait: aTrait) selectors. self basicLocalSelectors: self basicLocalSelectors , selectors. self removeFromComposition: aTrait. My guess is that the culprit for this is the method Behavior>>removeFromComposition:, which removes the trait both from the instance and the class side. While the trait selectors were added to the instance side, they are not to the class side and therefore they are gone after the flattening. I was able to fix this by changing the method to: flattenDown: aTrait | selectors classSelectors transformation classTransformation | [self hasTraitComposition and: [self traitComposition allTraits includes: aTrait]] assert. transformation := self traitComposition transformationOfTrait: aTrait. selectors := transformation selectors. classSelectors := classTransformation selectors. self basicLocalSelectors: (self basicLocalSelectors ifNil:[selectors] ifNotNil:[:bs | bs, selectors]). self class basicLocalSelectors: (self class basicLocalSelectors ifNil:[classSelectors] ifNotNil:[:bs | bs, classSelectors]). self removeFromComposition: aTrait. My fix feels more like a workaround than a real solution to the problem, so before that I submit a patch to the inbox I was wondering if someone with more knowledge regarding the traits implementation has any input on this ... Cheers, Andy
Hi, I just got done reading the paper "Traits: Composable Units of Behaviour". In general, I think the concept is massively underrated and has tons of potential. I can recommend the paper to anyone to make up one's mind about inheritance issues. I did not yet try to use traits in Pharo, myself. But Two things came to my mind that were not quite clear from your paper, Stef and other authors in case you are following this list... * Why aren't getter methods defined within a trait? Imho that would make a lot of sense. If you apply a trait, but don't like the getter/setter, then override it - no big deal. Why don't you include them as default in the trait? * When do unresolved conflicts error? Runtime vs. compile-time? Thanks, and keep it up. Markus
On Feb 2, 2012, at 6:27 PM, Markus Rother wrote:
Hi,
I just got done reading the paper "Traits: Composable Units of Behaviour". In general, I think the concept is massively underrated and has tons of potential. I can recommend the paper to anyone to make up one's mind about inheritance issues.
I did not yet try to use traits in Pharo, myself. But Two things came to my mind that were not quite clear from your paper, Stef and other authors in case you are following this list...
* Why aren't getter methods defined within a trait? Imho that would make a lot of sense. If you apply a trait, but don't like the getter/setter, then override it - no big deal. Why don't you include them as default in the trait?
because we did not know at compile time of the accessor the offset of the instance variables. Now I would love seen people doing another pass on what we did. And I would love to have slot and other cool compiler infrastructure and meta model so that we can rethink everything.
* When do unresolved conflicts error? Runtime vs. compile-time?
composition time
Thanks, and keep it up. Markus
participants (3)
-
Andy Kellens -
Markus Rother -
Stéphane Ducasse