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.
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 iPhone
On 20 May 2019, at 20:16, Dale Henrichs
<dale.henri...@gemtalksystems.com
<mailto:dale.henri...@gemtalksystems.com>> wrote:
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:
* 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