December 21, 2024
The Protocol of Symbol
Symbol is a subclass of String and is an abstract class with, like String, two concrete subclasses ByteSymbol and TwoByteSymbol. Again the storage set aside for ASCII or 'exotic' characters dictates the class of the symbol object and once a symbol is written LearningWorks handles this for us.
Here are a few rules about creating symbols.
A symbol is created by either preceding a literal string with a # as in
#'Into the Mystic'
or, if no spaces are present and the first character is non-alphanumeric. Here are some examples to illustrate the correct, and incorrect, syntax for Smalltalk symbols.
#CousinDupree "correct
syntax"
#Cousin Dupree# "incorrect
syntax"
200Motels "incorrect
syntax"
#200 Motels "incorrect
syntax"
#'200Motels' "correct
syntax"
#'200 Motels' "correct
syntax"
#RevolutionNo.9 "correct
syntax"
#RevolutionNo. 9 "incorrect
syntax"
Symbols are unique. Smalltalk uses the Symbol class to store, in a table, all the symbols that are created. If you write one that isn't stored, Smalltalk will, after checking this table, add the new symbol. To answer with this table, simply evaluate
Symbol table
In my Learning Works, evaluating
Symbol table size
returned 1777, with each of these elements referencing an instant of a class WeakArray. These arrays contained references to symbols and in one I found #baconArray. Smalltalk had added this to the table when I created the variable fom an earlier exercise.
To confirm a symbol's uniqueness, use the == message selector
#baconArray == #baconArray "answers true"
Compare this with
'baconArray' == 'baconArray' "answers false"
Interestingly
#baconArray == # baconArray "answers true"
spacing between # and the first character is ignored.
Symbols are used as keys in dictionaries. Finding a symbol is quicker than searching for a string. The includesKey: method in Dictionary results in each key being sent the message =. If the key is a symbol, the = method being implemented is:
= anObject
"Answer whether the receiver and the argument are
the same object
(have the same object pointer)."
^self == anObject
The test becomes one of identity rather than equality. This test for object identity is implemented as a system primitive. The memory address of the receiver and the argument are compared and it is this process that guarantees speed. This contrasts with a key written as a string. = as implemented in String requires a longer process of checking.
= aString
"Answer whether the argument is a string, and is
not a symbol, and
the receiver's size is the same as aString's size,
and each of the
receiver's elements equal the corresponding element
of aString"
| size |
aString isString ifFalse: [^false].
aString isSymbol ifTrue: [^false].
(size := self size) = aString size ifFalse: [^false].
1 to: size do: [:index | (self at: index) = (aString
at: index)
ifFalse:
[^false]].
^true
Symbols are fixed size so you cannot use a message such as
add:
A symbol cannot be changed, therefore Symbol
does not implement at:put:
You can use the concatenate copying message ,
(just a comma) whereby a string is returned. For example:
#The,#_,#Beach,#_,#Boys "answers 'The_Beach_Boys'"
Other selectors in the protocol should be familiar
#BrianWilson at: 1 "answers
$B "16r0042" a Character object"
#'Fun,Fun,Fun' size "answers
11"
You can't write #Fun,Fun,Fun because Smalltalk reads the expression and sees the symbol #Fun receiving a concatenate selector , followed by an undeclared variable Fun. This will result in an error.
#'Surf''sUp' indexOf: $' "answers
5"
#Fagen_and_Becker isEmpty "answers
false"
#Blue includes: $u "answers
true"
#aja asUppercase "answers
'AJA'"
#AJA asLowercase "answers
'aja'"
#'6345789' asString "answers
'6345789'"
'6345789' asSymbol "answers
#6345789 2
Symbol also implements the enumerating messages that we have met
do:
detect:ifNone:
keysAndValuesDo:
Next page » OrderedCollection
Previous page « The protocol of String
⇑ Up to top of page