The information on this page refers to versions < 5.
Managing Globals #
Let us assume a CompiledMethod is referenced from the graph to serialize. Sometimes we may be interested in storing just the selector and name of the class, because we know it will be present when materializing the graph. However, sometimes we want to really store the method with full detail.This means that given an object graph, there is not an unique way of serializing it. Fuel offers dynamic and static mechanisms to customize this.
Default Globals #
By default, Fuel considers following objects as globals, i.e. will store just its name:
nil
,true
,false
, andSmalltalk globals
.- Any
Class
,Trait
,Metaclass
orClassTrait
. - Any
CompiledMethod
(except when either it#isInstalled
not or#isDoIt
, for example, the code is evaluated from Workspace). - Some well-known global variables:
Smalltalk
SourceFiles
Transcript
Undeclared
Display
TextConstants
ActiveWorld
ActiveHand
ActiveEvent
Sensor
Processor
ImageImports
SystemOrganization
World
. Custom globals are duplicated In this following code snippet we show that by default the global value is not serialized as a global, and so it is duplicated on materialization.
"Define a global variable named #SomeGlobal."
SomeGlobal := Set new.
"Serialize and materialize the value of #SomeGlobal."
FLSerializer
serialize: SomeGlobal
toFileNamed: 'g.fuel'.
"The materialized object *is not* the same as the global instance."
[ (FLMaterializer materializeFromFileNamed: 'g.fuel') ~~ SomeGlobal ] assert.
But…
How to avoid duplication
Instead, in the code below #considerGlobal:
is used to specify that it should be stored as global.
| aSerializer |
"Define a global variable named #SomeGlobal."
SomeGlobal := Set new.
aSerializer := FLSerializer newDefault.
"Tell the serializer to consider #SomeGlobal as global."
aSerializer analyzer considerGlobal: #SomeGlobal.
aSerializer
serialize: SomeGlobal
toFileNamed: 'g.fuel'.
"In this case, the materialized object *is* the same as the global instance."
[ (FLMaterializer materializeFromFileNamed: 'g.fuel') == SomeGlobal ] assert.
This feature is tested in tests-globals protocol of FLBasicSerializationTest
as well in FLGlobalEnvironmentTest
.
Changing the environment
It is possible to specify where the global will be looked-up during materialization. The method #globalEnvironment:
exists for that purpose, as the following example shows.
| aSerializer aMaterializer anEnvironment |
"Define a global variable named #SomeGlobal."
SomeGlobal := Set new.
"Tell the serializer to consider #SomeGlobal as global."
aSerializer := FLSerializer newDefault.
aSerializer analyzer considerGlobal: #SomeGlobal.
aSerializer
serialize: SomeGlobal
toFileNamed: 'g.fuel'.
"Override value for #SomeGlobal."
anEnvironment := Dictionary newFrom: Smalltalk globals.
anEnvironment at: #SomeGlobal put: {42}.
"In this case, the materialized object *is the same* as the global instance."
FileStream oldFileNamed: 'g.fuel' do: [ :aStream |
aStream binary.
aMaterializer := FLMaterializer newDefault.
"Set the environment"
aMaterializer globalEnvironment: anEnvironment.
[ (aMaterializer materializeFrom: aStream) root = {42} ] assert ]
This feature is tested in the class FLGlobalEnvironmentTest
. The global environment can be setted also for serialization (not only materialization), but we don’t include an example for that case.
Let us assume a CompiledMethod is referenced from the graph to serialize. Sometimes we may be interested in storing just the selector and name of the class, because we know it will be present when materializing the graph. However, sometimes we want to really store the method with full detail.
This means that given an object graph, there is not an unique way of serializing it. Fuel offers dynamic and static mechanisms to customize this.