VAST's way of declaring and/or initializing Shared Pools is different from other Smalltalk dialects, as it uses declaration methods by means of _PRAGMA_*
prefixed methods and %%PRAGMA DECLARE ...
content comment.
This way of declaring Shared Pools has the benefit of being able to declare the shared pool, its keys, and whether the values are constant, how the values are initialized, etc, everything in a single declaration.
In other dialects to declare a Shared Pool you must subclass SharedPool
, with the pool keys as class variables, and you initialize the values by means of a class side method (by convention #initialize
).
Since Tonel treats Shared Pools as classes we had to devise a way to provide interoperability with other dialects as well as to support write/load only within VAST.
When writing a Shared Pool declaration method, the Tonel Writer will convert such method into a SharedPool
subclass with a class side #initialize
to initialize its values.
E.g. The declaration method:
YourApp class>>#_PRAGMA_YourSharedPool
"%%PRAGMA DECLARE
(name: YourSharedPool isPool: true)
(pool: YourSharedPool declarations: (
(name: YSP_Key1 isConstant: true valueExpression: '1')
(name: YSP_Key2 isConstant: true valueExpression: '2')
)
Will be converted to a Tonel Class declaration file YourSharedPool.class.st
with the following contents:
Class {
#name : 'YourSharedPool',
#superclass : 'SharedPool',
#classVars : [
'YSP_Key1',
'YSP_Key1'
],
#type : 'variable',
#category : 'Your-App'
}
{
#category : 'Initializing'
}
YourSharedPool class >> initialize [
YSP_Key1 := 1.
YSP_Key2 := 2.
]
Continuing with the example above, we started from a single declaration method that did both the declaration and initialization of the shared pool and ended up with a class declaration and its initialization method. Looking at the Tonel file we couldn't tell whether such shared pool class definition was generated by VAST or by Pharo/GemStone.
The Tonel Loader will recognize a class that defines a shared pool (by simply checking whether its superclass is SharedPool
) and will convert such definition back into a declaration method.
But as you might have guessed the Tonel declaration doesn't know anything about whether values were constant, or if they are initialized as value expressions or any other special declaration syntax, it also doesn't know whether they were declared and initialized all at once or separately (as in other dialects).
So in order to support this the Tonel Loader will convert the above described example of YourSharedPool
from Tonel into:
YourApp class>>#_PRAGMA_YourSharedPool
"%%PRAGMA DECLARE
(name: YourSharedPool isPool: true)
(pool: YourSharedPool declarations: (
(name: YSP_Key1 pool: YourSharedPool isConstant: false valueExpression: '')
(name: YSP_Key2 pool: YourSharedPool isConstant: false valueExpression: '')
)
Add a reference the declared pool in the application definition:
Application subclass: #YourApp
instanceVariableNames: ''
classVariableNames: ''
poolDictionaries: 'YourSharedPool'
And then create an initialization method like the following:
YourApp class>>#_SHAREDPOOL_YourSharedPool_initialize
YSP_Key1 := 1.
YSP_Key2 := 2.
And invoke it after loading.
The _SHAREDPOOOL_%PoolName%_initialize
is just a convention used to identify the initialization methods, which when written back to Tonel will be converted again into a simple class definition as described before, but also considering this special selectors to define its initializer.
If the purpose of exporting to Tonel is just to have a file based version of your code that is only going to be loaded back into VAST or to workaround some issues with the handling of SharedPools then you can export their declarations directly as what they are: methods.
NOTE: By default the TonelWriter
doesn't convert Shared Pools, so you have to explictly set this option if you want to enable it, this can be done programmaticaly by instructing the TonelWriter
to perform the conversion as follows.
TonelWriter new
applications: (Array with: AbtContainerExamplesApp);
convertSharedPools; "<<-- this line"
writeProjectInto: aCfsPath.