Hi.
I've recently been playing around/using Traits in squeak. I am building a parser, and wanted to capture parts of the source that I couldn't parse and attach it to the most recently parsed part of the source. I used Traits to implement this (as opposed to making all the AST classes sub-class a master class to handle this, or adding these methods to all of the classes just to handle this temporary function), and it worked really well. Well enough I might try using traits for other uses going forward. However, I had as an original intent to remove the Trait from these classes in the future, but I can't figure out how to do this at all in the tools (or with the code) currently in Squeak. I could file out the code and remove the trait parts there, remove the classes from the system, and file in the modified code, but that seem way to manual for my purposes. Is there a way (UI, code) to make a class NOT use any traits after a class has a Trait assigned to it? -Chris |
Try this: Trait flattenTraitMethodsInClass: MyClass. This will flatten all the trait inherited methods in the given class. It will also create a method #traitInfo which keeps the original information so the trait could be recreated via: Trait restoreCompositionOf: MyClass. If you don't want to restore the composition, you can just delete the #traitInfo method. Cheers, - Andreas |
On Fri, Oct 19, 2012 at 1:39 AM, Andreas.Raab <[hidden email]> wrote:
> Chris Cunningham wrote >> Is there a way (UI, code) to make a class NOT use any traits after a >> class has a Trait assigned to it? > > Try this: > > Trait flattenTraitMethodsInClass: MyClass. That would probably work well, but I wanted to remove the Trait and all of the behavior related to the Trait from the class. I could do this and then delete the methods, but that isn't really efficient. I did find the 'right' way to do this. To add a trait to a class, you change the definition of the class in the browser to look like: Object subclass: #AClass uses: ATraitComposition instanceVariableNames: ... To remove that trait (and any others), change the definition to be: Object subclass: #AClass uses: Array new instanceVariableNames: ... This will remove the Trait and the behavior from the class (and, for that matter, change the class definition code snippit). Odd, but it works. In my case, the goal was a temporary trait usage while building the parser, with the intention of removing the behavior from all of the classes later. Or, of course, removing it from other classes that I accidentally added the trait to. -Chris |
So the problem is that simply removing the line
uses: ATraitCompostition from the class definition doesn't change the class. It is because Class >> #subclass:instanceVariableNames:classVariableNames:poolDictionaries:category: works differently than Class >> #subclass:uses:instanceVariableNames:classVariableNames:poolDictionaries:category: The former should also sets the TraitComposition of the new class (to an empty one). I think that notifying a class change in the latter is not right, because it might be a class creation too. Also, shouldn't the value of oldClass be the class itself if it exists instead of a copy of the superclass? The same is also true for the other class defition methods (variable*, weak*). Levente On Sat, 20 Oct 2012, Chris Cunningham wrote: > On Fri, Oct 19, 2012 at 1:39 AM, Andreas.Raab <[hidden email]> wrote: >> Chris Cunningham wrote >>> Is there a way (UI, code) to make a class NOT use any traits after a >>> class has a Trait assigned to it? >> >> Try this: >> >> Trait flattenTraitMethodsInClass: MyClass. > > That would probably work well, but I wanted to remove the Trait and > all of the behavior related to the Trait from the class. I could do > this and then delete the methods, but that isn't really efficient. > > I did find the 'right' way to do this. To add a trait to a class, you > change the definition of the class in the browser to look like: > > Object subclass: #AClass > uses: ATraitComposition > instanceVariableNames: ... > > To remove that trait (and any others), change the definition to be: > > Object subclass: #AClass > uses: Array new > instanceVariableNames: ... > > This will remove the Trait and the behavior from the class (and, for > that matter, change the class definition code snippit). Odd, but it > works. > > In my case, the goal was a temporary trait usage while building the > parser, with the intention of removing the behavior from all of the > classes later. Or, of course, removing it from other classes that I > accidentally added the trait to. > > -Chris > > |
In reply to this post by cbc
It is also interesting that when you modify a Trait message inside a
class (either directly in the browser or else during debbuging), there'll be a new message, particular to that class that diverges from the message in Traits, causing a kind of "overload" (two messages of the same name, one in the Traits definition other in the class definition). If developer doesn't get it ASAP, it can be source of huge trouble. CdAB On 21-10-2012 02:47, Chris Cunningham wrote: > On Fri, Oct 19, 2012 at 1:39 AM, Andreas.Raab <[hidden email]> wrote: >> Chris Cunningham wrote >>> Is there a way (UI, code) to make a class NOT use any traits after a >>> class has a Trait assigned to it? >> Try this: >> >> Trait flattenTraitMethodsInClass: MyClass. > That would probably work well, but I wanted to remove the Trait and > all of the behavior related to the Trait from the class. I could do > this and then delete the methods, but that isn't really efficient. > > I did find the 'right' way to do this. To add a trait to a class, you > change the definition of the class in the browser to look like: > > Object subclass: #AClass > uses: ATraitComposition > instanceVariableNames: ... > > To remove that trait (and any others), change the definition to be: > > Object subclass: #AClass > uses: Array new > instanceVariableNames: ... > > This will remove the Trait and the behavior from the class (and, for > that matter, change the class definition code snippit). Odd, but it > works. > > In my case, the goal was a temporary trait usage while building the > parser, with the intention of removing the behavior from all of the > classes later. Or, of course, removing it from other classes that I > accidentally added the trait to. > > -Chris > > signature.asc (267 bytes) Download Attachment |
On Sun, 21 Oct 2012, Casimiro de Almeida Barreto wrote:
> It is also interesting that when you modify a Trait message inside a > class (either directly in the browser or else during debbuging), > there'll be a new message, particular to that class that diverges from > the message in Traits, causing a kind of "overload" (two messages of the > same name, one in the Traits definition other in the class definition). > If developer doesn't get it ASAP, it can be source of huge trouble. I guess that's how Traits should work. Levente > > CdAB > > On 21-10-2012 02:47, Chris Cunningham wrote: >> On Fri, Oct 19, 2012 at 1:39 AM, Andreas.Raab <[hidden email]> wrote: >>> Chris Cunningham wrote >>>> Is there a way (UI, code) to make a class NOT use any traits after a >>>> class has a Trait assigned to it? >>> Try this: >>> >>> Trait flattenTraitMethodsInClass: MyClass. >> That would probably work well, but I wanted to remove the Trait and >> all of the behavior related to the Trait from the class. I could do >> this and then delete the methods, but that isn't really efficient. >> >> I did find the 'right' way to do this. To add a trait to a class, you >> change the definition of the class in the browser to look like: >> >> Object subclass: #AClass >> uses: ATraitComposition >> instanceVariableNames: ... >> >> To remove that trait (and any others), change the definition to be: >> >> Object subclass: #AClass >> uses: Array new >> instanceVariableNames: ... >> >> This will remove the Trait and the behavior from the class (and, for >> that matter, change the class definition code snippit). Odd, but it >> works. >> >> In my case, the goal was a temporary trait usage while building the >> parser, with the intention of removing the behavior from all of the >> classes later. Or, of course, removing it from other classes that I >> accidentally added the trait to. >> >> -Chris >> >> > > > |
On 21-10-2012 22:49, Levente Uzonyi wrote:
> On Sun, 21 Oct 2012, Casimiro de Almeida Barreto wrote: > >> It is also interesting that when you modify a Trait message inside a >> class (either directly in the browser or else during debbuging), >> there'll be a new message, particular to that class that diverges from >> the message in Traits, causing a kind of "overload" (two messages of the >> same name, one in the Traits definition other in the class definition). >> If developer doesn't get it ASAP, it can be source of huge trouble. > > I guess that's how Traits should work. Because sometimes developer is tempted to correct things from/inside debugger. Then he'll have two versions of the method: a corrected version for the class in question and a wrong version elsewhere. CdAB > > > Levente > >> >> CdAB >> >> On 21-10-2012 02:47, Chris Cunningham wrote: >>> On Fri, Oct 19, 2012 at 1:39 AM, Andreas.Raab <[hidden email]> >>> wrote: >>>> Chris Cunningham wrote >>>>> Is there a way (UI, code) to make a class NOT use any traits after a >>>>> class has a Trait assigned to it? >>>> Try this: >>>> >>>> Trait flattenTraitMethodsInClass: MyClass. >>> That would probably work well, but I wanted to remove the Trait and >>> all of the behavior related to the Trait from the class. I could do >>> this and then delete the methods, but that isn't really efficient. >>> >>> I did find the 'right' way to do this. To add a trait to a class, you >>> change the definition of the class in the browser to look like: >>> >>> Object subclass: #AClass >>> uses: ATraitComposition >>> instanceVariableNames: ... >>> >>> To remove that trait (and any others), change the definition to be: >>> >>> Object subclass: #AClass >>> uses: Array new >>> instanceVariableNames: ... >>> >>> This will remove the Trait and the behavior from the class (and, for >>> that matter, change the class definition code snippit). Odd, but it >>> works. >>> >>> In my case, the goal was a temporary trait usage while building the >>> parser, with the intention of removing the behavior from all of the >>> classes later. Or, of course, removing it from other classes that I >>> accidentally added the trait to. >>> >>> -Chris >>> >>> >> >> >> > > signature.asc (267 bytes) Download Attachment |
On Mon, 22 Oct 2012, Casimiro de Almeida Barreto wrote:
> On 21-10-2012 22:49, Levente Uzonyi wrote: >> On Sun, 21 Oct 2012, Casimiro de Almeida Barreto wrote: >> >>> It is also interesting that when you modify a Trait message inside a >>> class (either directly in the browser or else during debbuging), >>> there'll be a new message, particular to that class that diverges from >>> the message in Traits, causing a kind of "overload" (two messages of the >>> same name, one in the Traits definition other in the class definition). >>> If developer doesn't get it ASAP, it can be source of huge trouble. >> >> I guess that's how Traits should work. > So so... > > Because sometimes developer is tempted to correct things from/inside > debugger. Then he'll have two versions of the method: a corrected > version for the class in question and a wrong version elsewhere. Better tools could help avoid these issues, but support for Traits is still minimal. Levente > > CdAB >> >> >> Levente >> >>> >>> CdAB >>> >>> On 21-10-2012 02:47, Chris Cunningham wrote: >>>> On Fri, Oct 19, 2012 at 1:39 AM, Andreas.Raab <[hidden email]> >>>> wrote: >>>>> Chris Cunningham wrote >>>>>> Is there a way (UI, code) to make a class NOT use any traits after a >>>>>> class has a Trait assigned to it? >>>>> Try this: >>>>> >>>>> Trait flattenTraitMethodsInClass: MyClass. >>>> That would probably work well, but I wanted to remove the Trait and >>>> all of the behavior related to the Trait from the class. I could do >>>> this and then delete the methods, but that isn't really efficient. >>>> >>>> I did find the 'right' way to do this. To add a trait to a class, you >>>> change the definition of the class in the browser to look like: >>>> >>>> Object subclass: #AClass >>>> uses: ATraitComposition >>>> instanceVariableNames: ... >>>> >>>> To remove that trait (and any others), change the definition to be: >>>> >>>> Object subclass: #AClass >>>> uses: Array new >>>> instanceVariableNames: ... >>>> >>>> This will remove the Trait and the behavior from the class (and, for >>>> that matter, change the class definition code snippit). Odd, but it >>>> works. >>>> >>>> In my case, the goal was a temporary trait usage while building the >>>> parser, with the intention of removing the behavior from all of the >>>> classes later. Or, of course, removing it from other classes that I >>>> accidentally added the trait to. >>>> >>>> -Chris >>>> >>>> >>> >>> >>> >> >> > > > |
In reply to this post by Levente Uzonyi-2
On Sun, Oct 21, 2012 at 7:33 AM, Levente Uzonyi <[hidden email]> wrote:
> So the problem is that simply removing the line > > uses: ATraitCompostition > > from the class definition doesn't change the class. It is because > > Class >> > #subclass:instanceVariableNames:classVariableNames:poolDictionaries:category: > > works differently than > > Class >> > #subclass:uses:instanceVariableNames:classVariableNames:poolDictionaries:category: > Yes, this is/was my problem. Thanks for clarifying it. -Chris |
Free forum by Nabble | Edit this page |