Like in Java, C# etc. How would I define something like enum Direction { input, output }
in Smalltalk?
The most trivial approach is to have class-side methods returning symbols or other basic objects (such as integers).
So you can write your example as follows:
Direction class>>input
^ #input
Direction class>>output
^ #output
And the usage:
Direction input
The main downsides are:
^ self name + '::input'
)A better way is to create your own enum object and return instances of it.
Such object should:
=
and hash
, so you can compare them by your value and use the enum as key in hashed collections (dictionaries)printOn:
method to ease debuggingIt could look something like this
Object subclass: #DirectionEnum
slots: { #value }
classVariables: { }
category: 'DirectionEnum'
"enum accessors"
DirectionEnum class>>input
^ self new value: #input
DirectionEnum class>>output
^ self new value: #output
"getter/setters"
DirectionEnum>>value
^ value
DirectionEnum>>value: aValue
value := aValue
"comparing"
DirectionEnum>>= anEnum
^ self class = anEnum class and: [ self value = anEnum value ]
DirectionEnum>>hash
^ self class hash bitXor: self value hash
"printing"
DirectionEnum>>printOn: aStream
super printOn: aStream.
aStream << '(' << self value asString << ')'
the usage is still the same
Direction input.
DirectionEnum output asString. "'a DirectionEnum(output)'"
and the problems mentioned in the trivial approach are resolved.
Obviously this is much more work, but the result is better. If you have many enums, then it could make sense to move the basic behavior to a new superclass Enum
, and then DirectionEnum
would just need to contain the class-side methods.