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?
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 ...
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?
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
Tim
Sent from my iPhoneTim,
I know that this doesn't answer your question, but one of the features that I'm building into Rowan is just this capability:
- project definitions composed of package definitions
- package definitions composed of class and class extension definitions
- class and class extensions definitions composed of method definitions
... 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