Tobias Pape uploaded a new version of Tools to project The Trunk:
http://source.squeak.org/trunk/Tools-topa.721.mcz ==================== Summary ==================== Name: Tools-topa.721 Author: topa Time: 29 November 2016, 3:27:14.942944 pm UUID: 2d64a7b9-8dcb-46fd-9371-c9dcb3f9cfd1 Ancestors: Tools-mt.720 Accessor generation. Makes for a nice class hook and pushes responsibility to the class. =============== Diff against Tools-mt.720 =============== Item was added: + ----- Method: Behavior>>createGetterFor: (in category '*Tools-Browser-accessors') ----- + createGetterFor: aName + + | code | + code := '{1}\ <generated>\\ ^ {1}\' withCRs format: {aName.}. + self compile: code classified: #accessing notifying: nil.! Item was added: + ----- Method: Behavior>>createInstVarAccessors (in category '*Tools-Browser-accessors') ----- + createInstVarAccessors + "Create getters and setters for all inst vars defined here, + except do NOT clobber or override any selectors already understood by me" + + self instVarNames + collect: [:each | each asSymbol] + thenDo: [:instVar | + (self canUnderstand: instVar) ifFalse: [self createGetterFor: instVar]. + (self canUnderstand: instVar asMutator) ifFalse: [self createSetterFor: instVar]]. + + ! Item was added: + ----- Method: Behavior>>createSetterFor: (in category '*Tools-Browser-accessors') ----- + createSetterFor: aName + + | code | + code := '{1}: anObject\ <generated>\\ {2}{1} := anObject.\' withCRs + format: {aName. self settersReturnValue ifTrue: ['^ '] ifFalse: [''].}. + self compile: code classified: #accessing notifying: nil.! Item was changed: ----- Method: Browser>>createInstVarAccessors (in category 'class functions') ----- createInstVarAccessors - "Create getters and setters for all inst vars defined at the level of the current class selection, - except do NOT clobber or override any selectors already understood by the instances of the selected class" + self selectedClassOrMetaClass + ifNotNil: [:aClass | aClass createInstVarAccessors]. + ! - self selectedClassOrMetaClass ifNotNil: - [:aClass| | cr | - cr := String with: Character cr. - aClass instVarNames do: - [:aName | | newMessage setter | - (aClass canUnderstand: aName asSymbol) ifFalse: - [newMessage := - aName, cr, cr, - ' ^ ', aName. - aClass compile: newMessage classified: #accessing notifying: nil]. - (aClass canUnderstand: (setter := aName, ':') asSymbol) ifFalse: - [newMessage := - setter, ' anObject', cr, cr, - (aClass settersReturnValue ifTrue: [' ^'] ifFalse: [' ']), - aName, ' := anObject'. - aClass compile: newMessage classified: #accessing notifying: nil]]]! |
Hey Tobias, it looks like you added a <generated> tag too.
Traditionally, the purpose of such a tag is used by code-generating applications to let programmers know that a particular piece of code is the purview of the framework which generated it, so they would know not to change it since it could very likely be regenerated in the future, blowing away any custom changes they might make there. But none of that is the case here. This is not to improve cooperation with a mysterious framework, but invoked directly by the developer out for a one-time convenience, just like when they use the clipboard. Such a tag could actually confuse or deter future developers from adding; e.g., lazy-initialization into the method, because its not part of a code-generating application. IMO, we should not put a <generated> tag in one-time-generated getters and setters. On Tue, Nov 29, 2016 at 8:31 AM, <[hidden email]> wrote: > Tobias Pape uploaded a new version of Tools to project The Trunk: > http://source.squeak.org/trunk/Tools-topa.721.mcz > > ==================== Summary ==================== > > Name: Tools-topa.721 > Author: topa > Time: 29 November 2016, 3:27:14.942944 pm > UUID: 2d64a7b9-8dcb-46fd-9371-c9dcb3f9cfd1 > Ancestors: Tools-mt.720 > > Accessor generation. > > Makes for a nice class hook and pushes responsibility to the class. > > =============== Diff against Tools-mt.720 =============== > > Item was added: > + ----- Method: Behavior>>createGetterFor: (in category '*Tools-Browser-accessors') ----- > + createGetterFor: aName > + > + | code | > + code := '{1}\ <generated>\\ ^ {1}\' withCRs format: {aName.}. > + self compile: code classified: #accessing notifying: nil.! > > Item was added: > + ----- Method: Behavior>>createInstVarAccessors (in category '*Tools-Browser-accessors') ----- > + createInstVarAccessors > + "Create getters and setters for all inst vars defined here, > + except do NOT clobber or override any selectors already understood by me" > + > + self instVarNames > + collect: [:each | each asSymbol] > + thenDo: [:instVar | > + (self canUnderstand: instVar) ifFalse: [self createGetterFor: instVar]. > + (self canUnderstand: instVar asMutator) ifFalse: [self createSetterFor: instVar]]. > + > + ! > > Item was added: > + ----- Method: Behavior>>createSetterFor: (in category '*Tools-Browser-accessors') ----- > + createSetterFor: aName > + > + | code | > + code := '{1}: anObject\ <generated>\\ {2}{1} := anObject.\' withCRs > + format: {aName. self settersReturnValue ifTrue: ['^ '] ifFalse: [''].}. > + self compile: code classified: #accessing notifying: nil.! > > Item was changed: > ----- Method: Browser>>createInstVarAccessors (in category 'class functions') ----- > createInstVarAccessors > - "Create getters and setters for all inst vars defined at the level of the current class selection, > - except do NOT clobber or override any selectors already understood by the instances of the selected class" > > + self selectedClassOrMetaClass > + ifNotNil: [:aClass | aClass createInstVarAccessors]. > + ! > - self selectedClassOrMetaClass ifNotNil: > - [:aClass| | cr | > - cr := String with: Character cr. > - aClass instVarNames do: > - [:aName | | newMessage setter | > - (aClass canUnderstand: aName asSymbol) ifFalse: > - [newMessage := > - aName, cr, cr, > - ' ^ ', aName. > - aClass compile: newMessage classified: #accessing notifying: nil]. > - (aClass canUnderstand: (setter := aName, ':') asSymbol) ifFalse: > - [newMessage := > - setter, ' anObject', cr, cr, > - (aClass settersReturnValue ifTrue: [' ^'] ifFalse: [' ']), > - aName, ' := anObject'. > - aClass compile: newMessage classified: #accessing notifying: nil]]]! > > |
On 30.11.2016, at 00:34, Chris Muller <[hidden email]> wrote: > Hey Tobias, it looks like you added a <generated> tag too. > Traditionally, the purpose of such a tag is used by code-generating > applications to let programmers know that a particular piece of code > is the purview of the framework which generated it, so they would know > not to change it since it could very likely be regenerated in the > future, blowing away any custom changes they might make there. > > But none of that is the case here. This is not to improve cooperation > with a mysterious framework, but invoked directly by the developer out > for a one-time convenience, just like when they use the clipboard. > Such a tag could actually confuse or deter future developers from > adding; e.g., lazy-initialization into the method, because its not > part of a code-generating application. > > IMO, we should not put a <generated> tag in one-time-generated getters > and setters. ¯\_(ツ)_/¯ what about <autoaccessor>? I'd rather to have a way to identify non-human made code, whether transient or permanent. -t > > On Tue, Nov 29, 2016 at 8:31 AM, <[hidden email]> wrote: >> Tobias Pape uploaded a new version of Tools to project The Trunk: >> http://source.squeak.org/trunk/Tools-topa.721.mcz >> >> ==================== Summary ==================== >> >> Name: Tools-topa.721 >> Author: topa >> Time: 29 November 2016, 3:27:14.942944 pm >> UUID: 2d64a7b9-8dcb-46fd-9371-c9dcb3f9cfd1 >> Ancestors: Tools-mt.720 >> >> Accessor generation. >> >> Makes for a nice class hook and pushes responsibility to the class. >> >> =============== Diff against Tools-mt.720 =============== >> >> Item was added: >> + ----- Method: Behavior>>createGetterFor: (in category '*Tools-Browser-accessors') ----- >> + createGetterFor: aName >> + >> + | code | >> + code := '{1}\ <generated>\\ ^ {1}\' withCRs format: {aName.}. >> + self compile: code classified: #accessing notifying: nil.! >> >> Item was added: >> + ----- Method: Behavior>>createInstVarAccessors (in category '*Tools-Browser-accessors') ----- >> + createInstVarAccessors >> + "Create getters and setters for all inst vars defined here, >> + except do NOT clobber or override any selectors already understood by me" >> + >> + self instVarNames >> + collect: [:each | each asSymbol] >> + thenDo: [:instVar | >> + (self canUnderstand: instVar) ifFalse: [self createGetterFor: instVar]. >> + (self canUnderstand: instVar asMutator) ifFalse: [self createSetterFor: instVar]]. >> + >> + ! >> >> Item was added: >> + ----- Method: Behavior>>createSetterFor: (in category '*Tools-Browser-accessors') ----- >> + createSetterFor: aName >> + >> + | code | >> + code := '{1}: anObject\ <generated>\\ {2}{1} := anObject.\' withCRs >> + format: {aName. self settersReturnValue ifTrue: ['^ '] ifFalse: [''].}. >> + self compile: code classified: #accessing notifying: nil.! >> >> Item was changed: >> ----- Method: Browser>>createInstVarAccessors (in category 'class functions') ----- >> createInstVarAccessors >> - "Create getters and setters for all inst vars defined at the level of the current class selection, >> - except do NOT clobber or override any selectors already understood by the instances of the selected class" >> >> + self selectedClassOrMetaClass >> + ifNotNil: [:aClass | aClass createInstVarAccessors]. >> + ! >> - self selectedClassOrMetaClass ifNotNil: >> - [:aClass| | cr | >> - cr := String with: Character cr. >> - aClass instVarNames do: >> - [:aName | | newMessage setter | >> - (aClass canUnderstand: aName asSymbol) ifFalse: >> - [newMessage := >> - aName, cr, cr, >> - ' ^ ', aName. >> - aClass compile: newMessage classified: #accessing notifying: nil]. >> - (aClass canUnderstand: (setter := aName, ':') asSymbol) ifFalse: >> - [newMessage := >> - setter, ' anObject', cr, cr, >> - (aClass settersReturnValue ifTrue: [' ^'] ifFalse: [' ']), >> - aName, ' := anObject'. >> - aClass compile: newMessage classified: #accessing notifying: nil]]]! >> >> > |
> what about <autoaccessor>?
> I'd rather to have a way to identify non-human made code, whether transient > or permanent. +1 Stef |
In reply to this post by Tobias Pape
On Wed, 30 Nov 2016, Tobias Pape wrote:
> > On 30.11.2016, at 00:34, Chris Muller <[hidden email]> wrote: > >> Hey Tobias, it looks like you added a <generated> tag too. >> Traditionally, the purpose of such a tag is used by code-generating >> applications to let programmers know that a particular piece of code >> is the purview of the framework which generated it, so they would know >> not to change it since it could very likely be regenerated in the >> future, blowing away any custom changes they might make there. >> >> But none of that is the case here. This is not to improve cooperation >> with a mysterious framework, but invoked directly by the developer out >> for a one-time convenience, just like when they use the clipboard. >> Such a tag could actually confuse or deter future developers from >> adding; e.g., lazy-initialization into the method, because its not >> part of a code-generating application. >> >> IMO, we should not put a <generated> tag in one-time-generated getters >> and setters. > > > ¯\_(ツ)_/¯ > > what about <autoaccessor>? > I'd rather to have a way to identify non-human made code, whether transient > or permanent. (I would rather not use pragmas in these methods, because I don't see if they would ever be used. If I were really want to mark these methods, I'd use a different author or a category other than accessing.) Levente > > -t > > > >> >> On Tue, Nov 29, 2016 at 8:31 AM, <[hidden email]> wrote: >>> Tobias Pape uploaded a new version of Tools to project The Trunk: >>> http://source.squeak.org/trunk/Tools-topa.721.mcz >>> >>> ==================== Summary ==================== >>> >>> Name: Tools-topa.721 >>> Author: topa >>> Time: 29 November 2016, 3:27:14.942944 pm >>> UUID: 2d64a7b9-8dcb-46fd-9371-c9dcb3f9cfd1 >>> Ancestors: Tools-mt.720 >>> >>> Accessor generation. >>> >>> Makes for a nice class hook and pushes responsibility to the class. >>> >>> =============== Diff against Tools-mt.720 =============== >>> >>> Item was added: >>> + ----- Method: Behavior>>createGetterFor: (in category '*Tools-Browser-accessors') ----- >>> + createGetterFor: aName >>> + >>> + | code | >>> + code := '{1}\ <generated>\\ ^ {1}\' withCRs format: {aName.}. >>> + self compile: code classified: #accessing notifying: nil.! >>> >>> Item was added: >>> + ----- Method: Behavior>>createInstVarAccessors (in category '*Tools-Browser-accessors') ----- >>> + createInstVarAccessors >>> + "Create getters and setters for all inst vars defined here, >>> + except do NOT clobber or override any selectors already understood by me" >>> + >>> + self instVarNames >>> + collect: [:each | each asSymbol] >>> + thenDo: [:instVar | >>> + (self canUnderstand: instVar) ifFalse: [self createGetterFor: instVar]. >>> + (self canUnderstand: instVar asMutator) ifFalse: [self createSetterFor: instVar]]. >>> + >>> + ! >>> >>> Item was added: >>> + ----- Method: Behavior>>createSetterFor: (in category '*Tools-Browser-accessors') ----- >>> + createSetterFor: aName >>> + >>> + | code | >>> + code := '{1}: anObject\ <generated>\\ {2}{1} := anObject.\' withCRs >>> + format: {aName. self settersReturnValue ifTrue: ['^ '] ifFalse: [''].}. >>> + self compile: code classified: #accessing notifying: nil.! >>> >>> Item was changed: >>> ----- Method: Browser>>createInstVarAccessors (in category 'class functions') ----- >>> createInstVarAccessors >>> - "Create getters and setters for all inst vars defined at the level of the current class selection, >>> - except do NOT clobber or override any selectors already understood by the instances of the selected class" >>> >>> + self selectedClassOrMetaClass >>> + ifNotNil: [:aClass | aClass createInstVarAccessors]. >>> + ! >>> - self selectedClassOrMetaClass ifNotNil: >>> - [:aClass| | cr | >>> - cr := String with: Character cr. >>> - aClass instVarNames do: >>> - [:aName | | newMessage setter | >>> - (aClass canUnderstand: aName asSymbol) ifFalse: >>> - [newMessage := >>> - aName, cr, cr, >>> - ' ^ ', aName. >>> - aClass compile: newMessage classified: #accessing notifying: nil]. >>> - (aClass canUnderstand: (setter := aName, ':') asSymbol) ifFalse: >>> - [newMessage := >>> - setter, ' anObject', cr, cr, >>> - (aClass settersReturnValue ifTrue: [' ^'] ifFalse: [' ']), >>> - aName, ' := anObject'. >>> - aClass compile: newMessage classified: #accessing notifying: nil]]]! >>> >>> >> |
On 30.11.2016, at 09:40, Levente Uzonyi <[hidden email]> wrote: > On Wed, 30 Nov 2016, Tobias Pape wrote: > >> >> On 30.11.2016, at 00:34, Chris Muller <[hidden email]> wrote: >> >>> Hey Tobias, it looks like you added a <generated> tag too. >>> Traditionally, the purpose of such a tag is used by code-generating >>> applications to let programmers know that a particular piece of code >>> is the purview of the framework which generated it, so they would know >>> not to change it since it could very likely be regenerated in the >>> future, blowing away any custom changes they might make there. >>> But none of that is the case here. This is not to improve cooperation >>> with a mysterious framework, but invoked directly by the developer out >>> for a one-time convenience, just like when they use the clipboard. >>> Such a tag could actually confuse or deter future developers from >>> adding; e.g., lazy-initialization into the method, because its not >>> part of a code-generating application. >>> IMO, we should not put a <generated> tag in one-time-generated getters >>> and setters. >> >> >> ¯\_(ツ)_/¯ >> >> what about <autoaccessor>? >> I'd rather to have a way to identify non-human made code, whether transient >> or permanent. > > Why is that for this case? > > (I would rather not use pragmas in these methods, because I don't see if they would ever be used. If I were really want to mark these methods, I'd use a different author or a category other than accessing.) yeah, but its IMHO more appropriate to have "proper" metadata. I actually intended to make a new icon marker for those methods :) > > Levente > >> >> -t >> >> >> >>> On Tue, Nov 29, 2016 at 8:31 AM, <[hidden email]> wrote: >>>> Tobias Pape uploaded a new version of Tools to project The Trunk: >>>> http://source.squeak.org/trunk/Tools-topa.721.mcz >>>> ==================== Summary ==================== >>>> Name: Tools-topa.721 >>>> Author: topa >>>> Time: 29 November 2016, 3:27:14.942944 pm >>>> UUID: 2d64a7b9-8dcb-46fd-9371-c9dcb3f9cfd1 >>>> Ancestors: Tools-mt.720 >>>> Accessor generation. >>>> Makes for a nice class hook and pushes responsibility to the class. >>>> =============== Diff against Tools-mt.720 =============== >>>> Item was added: >>>> + ----- Method: Behavior>>createGetterFor: (in category '*Tools-Browser-accessors') ----- >>>> + createGetterFor: aName >>>> + >>>> + | code | >>>> + code := '{1}\ <generated>\\ ^ {1}\' withCRs format: {aName.}. >>>> + self compile: code classified: #accessing notifying: nil.! >>>> Item was added: >>>> + ----- Method: Behavior>>createInstVarAccessors (in category '*Tools-Browser-accessors') ----- >>>> + createInstVarAccessors >>>> + "Create getters and setters for all inst vars defined here, >>>> + except do NOT clobber or override any selectors already understood by me" >>>> + >>>> + self instVarNames >>>> + collect: [:each | each asSymbol] >>>> + thenDo: [:instVar | >>>> + (self canUnderstand: instVar) ifFalse: [self createGetterFor: instVar]. >>>> + (self canUnderstand: instVar asMutator) ifFalse: [self createSetterFor: instVar]]. >>>> + >>>> + ! >>>> Item was added: >>>> + ----- Method: Behavior>>createSetterFor: (in category '*Tools-Browser-accessors') ----- >>>> + createSetterFor: aName >>>> + >>>> + | code | >>>> + code := '{1}: anObject\ <generated>\\ {2}{1} := anObject.\' withCRs >>>> + format: {aName. self settersReturnValue ifTrue: ['^ '] ifFalse: [''].}. >>>> + self compile: code classified: #accessing notifying: nil.! >>>> Item was changed: >>>> ----- Method: Browser>>createInstVarAccessors (in category 'class functions') ----- >>>> createInstVarAccessors >>>> - "Create getters and setters for all inst vars defined at the level of the current class selection, >>>> - except do NOT clobber or override any selectors already understood by the instances of the selected class" >>>> + self selectedClassOrMetaClass >>>> + ifNotNil: [:aClass | aClass createInstVarAccessors]. >>>> + ! >>>> - self selectedClassOrMetaClass ifNotNil: >>>> - [:aClass| | cr | >>>> - cr := String with: Character cr. >>>> - aClass instVarNames do: >>>> - [:aName | | newMessage setter | >>>> - (aClass canUnderstand: aName asSymbol) ifFalse: >>>> - [newMessage := >>>> - aName, cr, cr, >>>> - ' ^ ', aName. >>>> - aClass compile: newMessage classified: #accessing notifying: nil]. >>>> - (aClass canUnderstand: (setter := aName, ':') asSymbol) ifFalse: >>>> - [newMessage := >>>> - setter, ' anObject', cr, cr, >>>> - (aClass settersReturnValue ifTrue: [' ^'] ifFalse: [' ']), >>>> - aName, ' := anObject'. >>>> - aClass compile: newMessage classified: #accessing notifying: nil]]]! |
On 30.11.2016, at 09:40, Levente Uzonyi <[hidden email]> wrote: > Agree with Chris and Levente: This is just a little shortcut for inserting code, it should not be littered with gratuitous annotations *if invoked from the menu interactively*. The menu item previously did this right, there is no reason to change its behavior. I can see you wanting to use these methods from elsewhere, in which case adding the annotation might be fine. Maybe you want to pass an "annotation" argument to these generators? Just not in the interactive case. - Bert - |
In reply to this post by Tobias Pape
> what about <autoaccessor>?
> I'd rather to have a way to identify non-human made code, whether transient > or permanent. The thing is, a human *did* made it by selecting that option off the menu. This type of tag should be for code that is generated unbeknownst to the developer, *and* which may be regenerated in the future. > yeah, but its IMHO more appropriate to have "proper" metadata. > I actually intended to make a new icon marker for those methods :) Are you saying you want to identify *plain* getter/setter methods with an icon in the methods list? That way, as a developer, if I'm editing another method in the same class, then I could see that icon and, without having to select it, know that it is a simple accessor and not something more complex like lazily initialized. Sounds pretty good, at first.. however this should probably be done by analyzing the bytecodes, not by a tag, because there will be hundreds of simple accessors which would not have it, and a few which did but were not simple because the developer didn't remove the tag. It seems like it would be hard to come to rely on something so inaccurate. |
On 11/30/16, Chris Muller <[hidden email]> wrote:
>> what about <autoaccessor>? >> I'd rather to have a way to identify non-human made code, whether >> transient >> or permanent. > > The thing is, a human *did* made it by selecting that option off the > menu. +1 > > This type of tag should be for code that is generated unbeknownst to > the developer, *and* which may be regenerated in the future. +1 >> yeah, but its IMHO more appropriate to have "proper" metadata. >> I actually intended to make a new icon marker for those methods :) > > Are you saying you want to identify *plain* getter/setter > methods with an icon in the methods list? That way, as a developer, > if I'm editing another method in the same class, then I could see that > icon and, without having to select it, know that it is a simple > accessor and not something more complex like lazily initialized. > Sounds pretty good, at first.. Yes > however this should probably be done > by analyzing the bytecodes, not by a tag, because there will be > hundreds of simple accessors which would not have it, and a few which > did but were not simple because the developer didn't remove the tag. > It seems like it would be hard to come to rely on something so > inaccurate. > > --Hannes |
Free forum by Nabble | Edit this page |