Hi - is there a way to iterate over all the code in a package (or class or baseline) in a generic way (to pretty print out class definitions, and methods - including extensions ).
I was kind of hoping that with TonelWriter and Fileout and Critics that we would have a generic visitor mechanism but it seems that all of them just implemented it again - which misses a big opportunity for refactoring so that when you want to reason/print/manipulate code - it would be more straight forward. Is there anything/anyone addressing this ? Or maybe I’ve missed an obvious trick somewhere? Tim Sent from my iPhone |
Tim, I know that this doesn't answer your question, but one of the features that I'm building into Rowan is just this capability:
... there are also definitions that cover what is now handled by
Metacello: conditional packages, package grouping and project
dependencies ... I am intending/hoping that Rowan will eventually be available for
Pharo:) ... I have to finish Rowan for GemStone first:) Dale On 5/19/19 10:23 AM, Tim Mackinnon
wrote:
Hi - is there a way to iterate over all the code in a package (or class or baseline) in a generic way (to pretty print out class definitions, and methods - including extensions ). I was kind of hoping that with TonelWriter and Fileout and Critics that we would have a generic visitor mechanism but it seems that all of them just implemented it again - which misses a big opportunity for refactoring so that when you want to reason/print/manipulate code - it would be more straight forward. Is there anything/anyone addressing this ? Or maybe I’ve missed an obvious trick somewhere? Tim Sent from my iPhone |
Hi Dale - thanks for chipping in. I’ve seen references to Rowan, but hadn’t investigated. Interesting.
Were you thinking of a standard visitor pattern (Gof) or something else? And/Or, Is this visiting piece already done, or would it help if we had such a beast in Pharo that you could then reuse for your purpose? As an aside, in a separate message, I was lamenting the complexity of managing 100 simple similar packages with the same dependency - would Rowan help with that? Tim
Sent from my iPhone
|
On 5/20/19 12:38 PM, Tim Mackinnon
wrote:
Hi Dale - thanks for chipping in. I’ve seen references to Rowan, but hadn’t investigated. Interesting. I haven't focused on visitors at the moment I am focusing on
building out the basic definition structure ... providing apis for
creating packages in projects, classes in packages and methods in
classes, etc. Currently I am using several flavors visitors for modifications
(visiting the result of comparing two project definitions) ... the
most interesting pattern is that the modification visitor is being
used to write only the changed structures to disk -- instead of
rewriting the whole package. A modification visitor is also used
by the loader to drive the loading process -- again identifying
the definitions that have changed and then applying those changes
to the image ... I haven't run into a use case where I needed to use a visitor on
the defintion structure itself ... so far doing
projectNamed:/packageNamed:/classNamed:/methodNamed: has met my
needs, but I would be interested to learn a bit more about the
application that you have in mind ...
I assume that you are referring to this email[1]? If so, then I do think that Rowan would simplify things as there as the whole structure is controlled by a definitions structure api, so there is an API for creating and managing packages/classes, so if you were going to add a new class that was supposed to be independently loadable then you would do something like the following: | project className | project := (Rowan projectNamed:'Exercise') asDefinition. className := 'Acronym'. packageName := 'Exercise-', className. ((project addPackageNamed: packageName toComponentNamed: className withConditions: 'gemstone' andGroup: 'core') addClassNamed: className super: 'Object' category: packageName) addInstanceMethod: 'foo ^1' protocol: 'accessing. ((project addPackageNamed: packageName, '-Test' toComponentNamed: className withConditions: 'gemstone' andGroup: 'test') addClassNamed: className, 'Test' super: 'TestCase' category: packageName) addInstanceMethod: 'test ...' protocol: 'testing. (project componentNamed: className) addComponent: 'ExercismTools'. project export. "to write project to disk" project load. "to load the project in the image" In Rowan, packages are not independently loadable. A component is
the loadable entity and it may be composed of one or more
conditional packages. A component has dependencies upon other
components ... One other thing about Rowan is that there is no
such thing as load order ... the components/packages are loaded
atomically, so dependencies may be circular. The #export method above, writes the package and component structure to disk, and the component would look like the following: RwComponentLoadConfiguration{ #name : 'Acronym', #version : '0.1.0', #conditionalPackages : { [ 'gemstone' ] : { 'core' : { #packageNames : [ 'Exercise-Acronym' ] }, 'test' : { #packageNames : [ 'Exercise-Acronym-Test' ] } } }, #componentNames : [ 'ExercismTools' ] } At the end of the day, you'd have 100 components (one for each exercise). A "well formed" component should have tests. For something to be independently loadable, it is absolutely necessary that the independent aspect be validated by tests ... so I added a Test class and package for Acronym:) ... ExecercismTools is a separate components with all of the
necessary packages and "prereqs" defined... Hopefully, I've given you a flavor of how I think your problem
would be addressed with Rowan ... The thing that I like is that
everything is a definition with an api for creating/maintaining
the definitions and all of the definitions exist independent of
the loaded image ... the definitions can be read/written from disk
without going through a load process ... Let me know what you think ... as these components are still
fluid at the moment, feedback will have a real impact on the end
product. Dale [1]
http://forum.world.st/The-baseline-complexity-of-tiny-big-projects-td5099495.html
|
In reply to this post by Tim Mackinnon
clarification embedded below On 5/20/19 3:43 PM, Dale Henrichs
wrote:
'ExercismDev' above and 'ExercismTools' should be the same component name ('ExercismDev' ?) ... this is the component name containing the required packages ...| project className | project := (Rowan projectNamed:'Exercise') asDefinition. className := 'Acronym'. packageName := 'Exercise-', className. ((project addPackageNamed: packageName toComponentNamed: className withConditions: 'gemstone' andGroup: 'core') addClassNamed: className super: 'Object' category: packageName) addInstanceMethod: 'foo ^1' protocol: 'accessing. ((project addPackageNamed: packageName, '-Test' toComponentNamed: className withConditions: 'gemstone' andGroup: 'test') addClassNamed: className, 'Test' super: 'TestCase' category: packageName) addInstanceMethod: 'test ...' protocol: 'testing. (project componentNamed: className) addComponent: 'ExercismDev'. project export. "to write project to disk" project load. "to load the project in the image" RwComponentLoadConfiguration{ #name : 'Acronym', #version : '0.1.0', #conditionalPackages : { [ 'gemstone' ] : { 'core' : { #packageNames : [ 'Exercise-Acronym' ] } 'test' : { #packageNames : [ 'Exercise-Acronym-Test' ] } } }, #componentNames : [ 'ExercismTools' ] } |
In reply to this post by Tim Mackinnon
> On 19 May 2019, at 19:23, Tim Mackinnon <[hidden email]> wrote: > > Hi - is there a way to iterate over all the code in a package (or class or baseline) in a generic way (to pretty print out class definitions, and methods - including extensions ). > > I was kind of hoping that with TonelWriter and Fileout and Critics that we would have a generic visitor mechanism but it seems that all of them just implemented it again - which misses a big opportunity for refactoring so that when you want to reason/print/manipulate code - it would be more straight forward. > > Is there anything/anyone addressing this ? Or maybe I’ve missed an obvious trick somewhere? > I think we always wanted to add some default “visitor” style way of iterate over the structure… I will add this higher on my priorities, because it actually should be quite simple. Marcus |
If you have any thoughts on direction, I could take a look - I did the “dirty” and reimplemented the methods like everyone else… but it really felt like I shouldn’t have had to…
So my code looked a bit like this (where I should have used some sort of visitor with my stream instantiated, or maybe I could pass through some block, I think) (exercise solutionClasses asSortedCollection: [ :a :b | a name <= b name ]) do: [ :class | (exercise exercisePackage extendsClass: class) ifTrue: [ class exPrintOutExtensionsFor: exercise exercisePackage on: s ] ifFalse: [ class exPrintOutOn: s ] ] ]. And then in ClassDescription I had methods like this (noticed I need to visit the definition, the comments, the categories for class and instance etc.: exPrintOutOn: aWriteStream "Print a description of the receiver on aWriteStream." aWriteStream nextPutAll: '"-- #', self name, ' (class) --"'; cr; cr; nextPutAll: self definition; nextPut: $.; cr; cr. self hasComment ifTrue: [ aWriteStream nextPut: $". self comment trimBoth encodeDoublingDoubleQuotesOn: aWriteStream. aWriteStream nextPut: $"; cr; cr ]. self exPrintOutCategoriesFor: self class on: aWriteStream. self exPrintOutCategoriesFor: self on: aWriteStream > On 13 Jun 2019, at 08:26, Marcus Denker <[hidden email]> wrote: > > > >> On 19 May 2019, at 19:23, Tim Mackinnon <[hidden email]> wrote: >> >> Hi - is there a way to iterate over all the code in a package (or class or baseline) in a generic way (to pretty print out class definitions, and methods - including extensions ). >> >> I was kind of hoping that with TonelWriter and Fileout and Critics that we would have a generic visitor mechanism but it seems that all of them just implemented it again - which misses a big opportunity for refactoring so that when you want to reason/print/manipulate code - it would be more straight forward. >> >> Is there anything/anyone addressing this ? Or maybe I’ve missed an obvious trick somewhere? >> > > I think we always wanted to add some default “visitor” style way of iterate over the structure… > > I will add this higher on my priorities, because it actually should be quite simple. > > > Marcus > > |
Free forum by Nabble | Edit this page |