Header

Let us assume a class is referenced from the graph to serialize. Sometimes we may be interested in storing just the name of the class because we know it will be present when materializing the graph. However, sometimes we want to really store the class with full detail, including its method dictionary, methods, class variables, etc. When serializing a package, we are interested in a mixture of both: for external classes, just the name but, for the internal ones, 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:

Adding custom globals

User can customize this using #considerGlobal: to add more globals. A demo:
| aSerializer anArray materializedArray |
"Prepare an array whose two elements are system globals."
anArray := Array with: Set new with: Set new.
Smalltalk at: #GlobalSet1 put: anArray first.
Smalltalk at: #GlobalSet2 put: anArray second.
"Serialize considering *only first* as a global object."
FileStream forceNewFileNamed: 'demo.fuel' do: [:aStream |
	aSerializer := FLSerializer newDefault.
	aSerializer analyzer considerGlobal: #GlobalSet1.
	aSerializer serialize: anArray on: aStream binary].

"Materialize"
FileStream oldFileNamed: 'demo.fuel' do: [:aStream |
	materializedArray := (FLMaterializer newDefault 
		materializeFrom: aStream binary) root].
	
"Check that second element is a new Set."
[ (Smalltalk at: #GlobalSet1) == materializedArray first ] assert.
[ (Smalltalk at: #GlobalSet2) ~~ materializedArray second ] assert.

Light vs. Full Serialization

In Fuel, we split the possible use scenarios on these two:
Light
For users who need to store plain objects, and if the graph points to a CompiledMethod or a Class, for example, always the intention will be to store them as globals (so, not in detail). Most users should fall in this scenario.
Full
When more complete and sophisticated serialization is needed, and you can specify to store certain behaviors and methods with full detail. This is used by experimental projects like package loaders, an object swapper, or remote execution. For more information, you can install DevelopmentGroup configuration and look at FuelMetalevelTests packages for examples. Don't hesitate to ask us.

Let us assume a class is referenced from the graph to serialize. Sometimes we may be interested in storing just the name of the class because we know it will be present when materializing the graph. However, sometimes we want to really store the class with full detail, including its method dictionary, methods, class variables, etc. When serializing a package, we are interested in a mixture of both: for external classes, just the name but, for the internal ones, 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, and the System Dictionary.
  • All Classes and Traits.
  • All Metaclasses and ClassTraits.
  • All CompiledMethods.
  • Some well-known global variables (Smalltalk SourceFiles Transcript Undeclared Display TextConstants ActiveWorld ActiveHand ActiveEvent Sensor Processor ImageImports SystemOrganization World)

Adding custom globals

User can customize this using #considerGlobal: to add more globals. A demo:

| aSerializer anArray materializedArray |
"Prepare an array whose two elements are system globals."
anArray := Array with: Set new with: Set new.
Smalltalk at: #GlobalSet1 put: anArray first.
Smalltalk at: #GlobalSet2 put: anArray second.
"Serialize considering *only first* as a global object."
FileStream forceNewFileNamed: 'demo.fuel' do: [:aStream |
	aSerializer := FLSerializer newDefault.
	aSerializer analyzer considerGlobal: #GlobalSet1.
	aSerializer serialize: anArray on: aStream binary].

"Materialize"
FileStream oldFileNamed: 'demo.fuel' do: [:aStream |
	materializedArray := (FLMaterializer newDefault 
		materializeFrom: aStream binary) root].
	
"Check that second element is a new Set."
[ (Smalltalk at: #GlobalSet1) == materializedArray first ] assert.
[ (Smalltalk at: #GlobalSet2) ~~ materializedArray second ] assert.

Light vs. Full Serialization

In Fuel, we split the possible use scenarios on these two:

Light
For users who need to store plain objects, and if the graph points to a CompiledMethod or a Class, for example, always the intention will be to store them as globals (so, not in detail). Most users should fall in this scenario.
Full
When more complete and sophisticated serialization is needed, and you can specify to store certain behaviors and methods with full detail. This is used by experimental projects like package loaders, an object swapper, or remote execution. For more information, you can install DevelopmentGroup configuration and look at FuelMetalevelTests packages for examples. Don't hesitate to ask us.