|
Class: Symbol
Object
|
+--Collection
|
+--SequenceableCollection
|
+--ArrayedCollection
|
+--UninterpretedBytes
|
+--CharacterArray
|
+--String
|
+--Symbol
- Package:
- stx:libbasic
- Category:
- Collections-Text
- Version:
- rev:
1.162
date: 2024/04/12 18:03:59
- user: stefan
- file: Symbol.st directory: libbasic
- module: stx stc-classLibrary: libbasic
Symbols represent unique strings - every symbol with same printString
exists exactly once in the system; Symbols are used for selectors, global
variable-keys etc. Symbols can also be used to represent things which are
enumeration type values in other programming languages (since symbols are
created at compile time, comparing them using == is a fast pointer compare).
A symbol may not change its characters - i.e. it is constant over its lifetime.
Other than that, symbols behave much like strings.
The most prominent use of symbols is as key for message sending: methods are stored
in a classes method dictionary, where symbols are used as key to map names to methods.
Also, symbols are used as key to map class names (global names) to actual class objects.
Special ST/X feature:
The ST/X VM method lookup supports selector namespaces for method extensions.
This means, that a class may contain method extensions in another namespace,
which are only seen and invoked if called from a class within that namespace.
Technically, this is done by storing the method under a special namespace-selector,
which is a symbol consisting of the user visible name, prefixed by ':<ns>::'.
The VM's method lookup algorithm contains special handling code for such constructs.
Thus, if two methods are stored as 'foo' and ':NS::foo' are present in a class,
any send of 'foo' from wíthin the NS-namespace will invoke the second method.
Any other send will invoke the first one.
copyrightCOPYRIGHT (c) 1988 by Claus Gittinger
All Rights Reserved
This software is furnished under a license and may be used
only in accordance with the terms of that license and with the
inclusion of the above copyright notice. This software may not
be provided or otherwise made available to, or used by, any
other person. No title to or ownership of the software is
hereby transferred.
Compatibility-ST80
-
tableSize
( an extension from the stx:libcompat package )
-
return the size of the system's symbol table
Compatibility-Squeak
-
allSymbols
( an extension from the stx:libcompat package )
-
self allSymbols
Javascript support
-
for: argument
-
Symbol.for(string) is the same as ST's string asSymbol
instance creation
-
basicNew: size
-
redefined to return a string instead of a symbol -
this allows all copy methods inherited from String to
return strings containing the symbol's characters.
Real symbols are only created with #intern: or #asSymbol.
-
fromString: aString
-
same as intern: for Symbol, but may be used to create interned instances
of subclasses.
Notice: this fails, if you try to intern an instance of a subclass, AND
a symbol with the same name already exists. In this case, the original
symbol is returned. To use it for enum-type symbols, make certain, that the
names are unique (for example by including the classes name as a prefix-string).
-
intern: aString
-
return a unique symbol with printname taken from the String-argument
-
internCharacter: aCharacter
-
return a unique symbol with printname taken from the Character-argument
-
new: size
-
redefined to return a string instead of a symbol -
this allows all copy methods inherited from String to
return strings containing the symbol's characters.
Real symbols are only created with intern: or asSymbol.
-
newUninternedFromString: aString
-
return a new uninterned symbol.
This will NOT be a unique symbol, but instead multiple instances with the same
characters may come into existance with this.
This is a very special method, only useful for compiler-(re)writers,
which need new temporary symbol instances, which should not be interned,
but still behave (and respond) to symbol messages.
For example, when code is rewritten, it might be useful for identifiers,
or for super private methods, which use these as selector
(but cannot be called, unless the selector is known by reference)
Usage example(s):
|s|
s := Symbol newUninternedFromString:'hello'.
s == #hello.
s isSymbol.
|
queries
-
allowWideSymbols
-
incomplete, experimental and not yet supported by stc
-
allowWideSymbols: aBoolean
-
incomplete, experimental and not yet supported by stc
-
findInterned: aString
-
for ST-80 compatibility - if the argument, aString is known
as Symbol, return this symbol. Otherwise return nil.
-
hasInterned: aString
-
return true, if the argument, aString is known as Symbol;
false otherwise
-
hasInterned: aString ifTrue: trueBlock
-
for ST-80 compatibility - if the argument, aString is known
as Symbol, evaluate the block with the corresponding symbol
as argument and return true; otherwise return false
-
hasSharedInstances
-
return true if this class can share instances when stored binary,
that is, instances with the same value can be stored by reference.
True returned here - there is only one of each symbol (per contents).
Compatibility-Squeak
-
cull: anObject
-
-
precedence
-
the precedence in an expression; 0 is highest;
unary < binary < keyword
Usage example(s):
self assert:(#foo precedence < #+ precedence).
self assert:(#+ precedence < #key: precedence).
self assert:(#foo precedence < #key: precedence).
|
Compatibility-VW
-
<< catalogID
-
create and return a new UserMessage, with the receiver as key,
and the argument as cataglogID.
VW compatibility.
Usage example(s):
(#theFooMessage << #myMessages)
(#theFooMessage << #myMessages >> 'cannot read subclass of metaclass')
(#theFooMessage >> 'cannot read subclass of metaclass')
|
-
>> aString
-
create and return a new UserMessage, with the receiver as key,
and the argument as defaultString.
VW compatibility.
Usage example(s):
(#theFooMessage << #myMessages)
(#theFooMessage << #myMessages >> 'cannot read subclass of metaclass')
(#theFooMessage >> 'cannot read subclass of metaclass')
|
accessing
-
basicAt: index put: something
-
report an error if an interned symbol is about to be changed
- interned symbols may NOT be changed.
For uninterned symbols, this is allowed.
-
formattedCode
( an extension from the stx:libtool package )
-
private helper for the CodeGenerator
-
nameSpace
-
if I have the format of a namespace-selector,
retrieve the namespace. Otherwise, return nil.
Also return nil, if that namespace does not exist (in contrast to nameSpacePart).
Namespace selectors have a special, fix defined format, which is also known in the VM.
They must be of the form :<ns>::<sel>,
where <ns> is the namespace and <sel> is the raw selector.
This special format (a symbol starting with a colon) was chosen, because almost every other selector
is legal, and this can be checked quickly by just looking at the first character.
Usage example(s):
#':foo:' nameSpace -> nil (bad format)
#':foo::bar' nameSpace -> nil (non existing)
#':Tools::bar' nameSpace -> Tools
#'bar' nameSpace -> nil
#'bar:' nameSpace -> nil
|
-
nameSpaceAndSelector
-
return a two element tuple consisting of the namespace and the raw selector.
If I do not have the format of a namespace-selector, or the namespace is non-existing,
the first element of the returned tuple will be nil.
Namespace selectors have a special, fix defined format, which is also known in the VM.
They must be of the form :<ns>::<sel>,
where <ns> is the namespace and <sel> is the raw selector.
This special format (a symbol starting with a colon) was chosen, because almost every other selector
is legal, and this can be checked quickly by just looking at the first character.
Usage example(s):
#':foo:bar' nameSpaceAndSelector -> #(nil #':foo:bar')
#':foo::bar' nameSpaceAndSelector -> #(nil #bar)
#':Tools::foo' nameSpaceAndSelector -> #(Tools (* NameSpace *) #foo)
|
-
nameSpaceAndSelectorParts
-
return a two element tuple consisting of the namespace name and the raw selector.
If I do not have the format of a namespace-selector,
the first element of the returned tuple will be nil.
Namespace selectors have a special, fix defined format, which is also known in the VM.
They must be of the form :<ns>::<sel>,
where <ns> is the namespace and <sel> is the raw selector.
This special format (a symbol starting with a colon) was chosen, because almost every other selector
is legal, and this can be checked quickly by just looking at the first character.
Usage example(s):
#':foo:bar' nameSpaceAndSelectorParts -> #(nil #':foo:bar')
#':foo:bar' nameSpaceAndSelector -> #(nil #':foo:bar')
#':foo::bar' nameSpaceAndSelectorParts -> #('foo' #bar)
#':foo::bar' nameSpaceAndSelector -> #(nil #bar)
#'bar' nameSpaceAndSelectorParts -> #(nil #bar)
#'bar' nameSpaceAndSelector -> #(nil #bar)
#':Tools::foo' nameSpaceAndSelectorParts -> #('Tools' #foo)
#':Tools::foo' nameSpaceAndSelector -> #(Tools (* NameSpace *) #foo)
|
-
nameSpacePart
-
if I have the format of a namespace-selector,
retrieve the namespace name. Otherwise, return nil.
Namespace selectors have a special, fix defined format, which is also known in the VM.
They must be of the form :<ns>::<sel>,
where <ns> is the namespace and <sel> is the raw selector.
This special format (a symbol starting with a colon) was chosen, because almost every other selector
is legal, and this can be checked quickly by just looking at the first character.
Usage example(s):
#':foo:' nameSpacePart -> nil (bad format)
#':foo::bar' nameSpacePart -> 'foo'
#':Tools::bar' nameSpacePart -> 'Tools'
|
-
selector
-
if I have the format of a namespace-selector, retrieve the raw selector.
Otherwise, return myself.
Namespace selectors have a special, fix defined format, which is also known in the VM.
They must be of the form :<ns>::<sel>,
where <ns> is the namespace and <sel> is the raw selector.
This special format (a symbol starting with a colon) was chosen,
because almost every other selector is legal,
and this can be checked quickly in the VM, by just looking at the first character.
** This is an obsolete interface - do not use it (it may vanish in future versions) **
-
selectorWithoutNameSpace
-
if I have the format of a namespace-selector, retrieve the raw selector.
Otherwise, return myself.
Namespace selectors have a special, fix defined format, which is also known in the VM.
They must be of the form :<ns>::<sel>,
where <ns> is the namespace and <sel> is the raw selector.
This special format (a symbol starting with a colon) was chosen, because almost every other selector
is legal, and this can be checked quickly by just looking at the first character.
Usage example(s):
#':foo:' selectorWithoutNameSpace -> #':foo:' (bad format)
#':foo::bar' selectorWithoutNameSpace -> #bar
#':Tools::bar' selectorWithoutNameSpace -> #bar
|
comparing
-
= something
-
return true, if the receiver and argument consist of the same characters.
Redefined here, for more efficient comparison of symbols
(which can to be compared using #==).
If the argument is a symbol, we use a quick pointer compare, instead of
the inherited value compare.
-
identityHash
-
interned symbols can return a better hash key
Usage example(s):
|hashColl hashSet|
hashColl := OrderedCollection new:20000.
Symbol allInstancesDo:[:instance |
hashColl add:instance identityHash
].
hashSet := hashColl asSet.
Transcript showCR:'Symbols: ', hashColl size printString,
' unique hash keys: ', hashSet size printString,
' collisions:', (hashColl size - hashSet size) printString.
|
-
~= something
-
return true, if the receiver and argument do not consist of the same characters.
Redefined here, for more efficient #~= comparison of symbols
(which ought to be compared using #~~).
If the argument is a symbol, we use a quick pointer compare, instead of
the inherited value compare.
converting
-
asClass
-
return the class named after me
Usage example(s):
#Array asClass
#Foo asClass
|
-
asClassIfAbsent: exceptionValue
-
return the class named after me
Usage example(s):
#Array asClassIfAbsent:123 => Array
#Foo asClassIfAbsent:123 => 123
|
-
asImmutableCollection
-
I am immutable
-
asMutableCollection
-
return a writable copy of myself
Usage example(s):
#Object asMutableCollection
|
-
asString
-
return a string with printname taken from mine
Usage example(s):
-
asSymbol
-
Return a unique symbol with the name taken from the receiver's characters.
Since I am a symbol - just return myself
-
asSymbolIfInterned
-
If a symbol with the receiver's characters is already known, return it.
Otherwise, return nil.
Since I am a symbol - just return myself
-
asSymbolIfInternedOrSelf
-
(comment from inherited method)
If a symbol with the receiver's characters is already known, return it.
Otherwise, return self.
This can be used to query for an existing symbol and is the same as:
self knownAsSymbol ifTrue:[self asSymbol] ifFalse:[self]
but slightly faster, since the symbol lookup operation is only performed once.
The receiver must be a singleByte-String.
TwoByte- and FourByteSymbols are (currently ?) not allowed.
-
beImmutable
-
I am already immutable
copying
-
copy
-
return a copy of myself
- reimplemented here since symbols are immutable.
-
deepCopy
-
return a copy of myself
- reimplemented here since symbols are immutable.
-
deepCopyUsing: aDictionary postCopySelector: postCopySelector
-
return a deep copy of myself
- reimplemented here since symbols are immutable.
-
shallowCopy
-
return a copy of myself
- reimplemented here since symbols are immutable and unique,
so we return the receiver.
-
simpleDeepCopy
-
return a copy of myself
- reimplemented here since symbols are immutable.
evaluation
-
value: anObject
-
this is sent by collection enumeration methods,
if a symbol is given instead of a block as loop-block argument
Usage example(s):
this enables the elegant construct:
#(1 2 3 4 5 6 7) collect:#negated
but also, as a side effect, this ugly thing (if the arg understands the receiver):
#negated value:#(1 2 3 4 5 6 7)
|
-
value: el value: arg
-
this is sent by collection enumeration methods,
if a symbol is given instead of a block as loop-block argument
inspecting
-
inspectorValueListIconFor: anInspector
( an extension from the stx:libtool package )
-
returns the icon to be shown alongside the value list of an inspector
-
inspectorValueStringInListFor: anInspector
( an extension from the stx:libtool package )
-
returns a string to be shown in the inspector's list
printing & storing
-
displayString
-
return a string used when displaying the receiver in a view;
for example an Inspector. This is usually the same as printString,
but sometimes redefined for a better look.
-
printOn: aStream
-
append a user printed representation of the receiver to aStream.
The format is suitable for a human - not meant to be read back.
In contrast to ST-80, this does return the symbols characters
without any leading #. Therefore, you can directly send symbols'
printStrings to some output device. This is incompatible, but easier
to use.
-
printString
-
return a printed representation of the receiver.
In contrast to ST-80, this does return the symbols characters
without any leading #. Therefore, you can directly send symbols'
printStrings to some output device. This is incompatible, but easier
to use.
-
storeOn: aStream
-
store myself on a stream
Usage example(s):
String streamContents:[:s|
#asInteger storeOn:s.
].
String streamContents:[:s|
#at:put: storeOn:s.
].
String streamContents:[:s|
#'at#+-:put:' storeOn:s.
].
|
-
storeString
-
return a String for storing the receiver
Usage example(s):
#'abc' storeString
#'abc:' storeString
#'abc:def:' storeString
#'abc:def' storeString
#'abc::def' storeString
#'abc &^*' storeString
#'abcdef::' storeString
#'hello''world' storeString
#'' storeString
#'''' storeString
#'_hello' storeString
#'123' storeString
|
private array element printing
-
displayAsArrayElementOn: aStream
-
Display myself as an Array element on a stream.
I am displayed as an array element, so the '#' may be omitted sometimes.
Take care for special symbols
-
printAsArrayElementOn: aStream
-
Print myself as an Array element on a stream.
I am printed as an array element, so the '#' may be omitted sometimes.
Take care for special symbols
-
storeAsArrayElementOn: aStream
-
store myself on a stream.
I am stored as an array element, so the '#' may be omitted sometimes.
Take care for special symbols
Usage example(s):
#(storeOn: #true #false #nil #'hokus pokus fidibus') storeAsArrayElementOn:Transcript
|
queries
-
species
-
when copying, or concatenating, return instances of this class
splitting & joining
-
split: aSequenceableCollection indicesDo: aBlock
-
let me split aSequenceableCollection
and evaluate aBlock for each fragment's start- and end-position.
I myself perform myself on every character
system primitives
-
become: anotherObject
-
make all references to the receiver become references to anotherObject
and vice-versa. For symbols, some special action is required, to
correctly handle a become of the global dictionaries.
Anyway: this is very dangerous - mysterous side-effects are to be
expected.
Notice: because of the danger here, this method may report an error
in future versions
-
becomeNil
-
make all references to the receiver become nil - effectively getting
rid of the receiver. For symbols, this is not allowed, if the receiver
is used as a key in some SystemDictionary.
This can be a very dangerous operation - be warned.
Notice: because of the danger here, this method may report an error
in future versions
-
grow: newSize
-
blocked
-
removeAll
-
blocked
testing
-
isImmutable
-
return true, if the receiver is immutable.
Since I am a symbol, return always true
-
isSingleByteString
-
returns true only for strings and immutable strings.
Must replace foo isMemberOf:String and foo class == String
-
isSymbol
-
return true, if the receiver is some kind of symbol.
Since I am a symbol, return always true
tracing
-
traceInto: aRequestor level: level from: referrer
-
double dispatch into tracer, passing my type implicitely in the selector
visiting
-
acceptVisitor: aVisitor with: aParameter
-
dispatch for visitor pattern; send #visitSymbol:with: to aVisitor
|