How to Write Portable Code
This page contains hints on how to write a portable code to make sure the code will run on both Pharo and Smalltalk/X without significant effort when merging.
- make sure no method refers to instance variables that are undeclared. Smalltalk/X refuses to commit and compile such methods for a very good reason. In Pharo, please do use UndeclaredChaser (see below) to check for undeclared variables.
- do not use Object>>asString. Not all Smalltalks implement it.
- do not use Object>>name. Not all Smalltalks implement it.
- do not use Dictionary>>keysAndValuesRemove:. Not all Smalltalks implement it.
- do not use Class>>methods The semantics is different among Smalltalks.
Class methodDictionary valuesinstead.
- when a class implements instance #initialize, make sure the class side method new sends it (or it inherits it from it's superclass in the same package). Do not depend on the fact that Pharo sends #initialize automatically - not all Smalltalks do this.
- do not pass parameters to
ifNil:[ ... ] ifNotNil: [ ... ]blocks.
^(self computeSomeObject) ifNotNil:[ :object | object ] ifNil:[ NullObject new ]
| object | object := self computeSomeObject. ^ object notNil ifTrue:[ object ] ifFalse:[ NullObject new ].
stc compiler cannot compile
ifNotNil:ifNil with parameters. Moreover, better use
notNil ifTrue:[ ... ] ifFalse: [ ... ] -
stc optimizes this better...
Using a UndeclaredChaser in Pharo
...specially crafted for Jan :-)
Gofer new url: 'http://smalltalkhub.com/mc/JanVrany/Misc/main'; package: 'UndeclaredChaser'; load.
Run chaser on packages, especially on PetitCompiler package. To do so, inspect result of following expression:
UndeclaredChaser new chaseIn: 'PetitCompiler'
If it's an empty collection, there are no undeclared. If not, there's a problem.
The collection contains associations from a CompiledMethod to name of the undeclared variable, i.e.,
if if contains
PEGFsaTransition>>#accepts:->#characterSet then it means that method
#accepts: in class
PEGFsaTransition refer to variable
characterSet which is actually not declared (neither local var, neither instvar).