Note. The following is implementation dependent. ANSI Smalltalk Standard defines:
It is not known whether the values โโof the same literals are the same or different objects. It is also not indicated whether the values โโof the individual ratings of a particular literal are the same or different objects.
That is, you cannot rely on two (equal) literals that are the same or different from others. However, the following general implementation
Literary arrays in Squeak and Pharo
At least in Squeak and Pharo, literal arrays are built when the method is saved (= compiled) and stored inside the method object (a CompiledMethod ). This means that changing the literal array changes the value stored in the method object. For instance:
MyClass>>example1 | literalArray | literalArray :=
This method returns 1 only ever on the first call:
| op | o := MyClass new. o example1. "==> 1" o example1. "==> 2" o example1. "==> 2" p := MyClass new. p example1. "==> 2"
It does not even depend on the recipient.
But then again, you cannot rely on this ; it may be different in other Smalltalks.
Different approaches
Copy (always safe)
To overcome this, you can simply copy an array of literals before using. Your example:
MyClass>>incrementedNumbers | numbers | numbers :=
This is always safe and will not mutate the array in the method object.
Bracketed arrays (mostly portable)
Although not defined in the standard, most implementations support expressed array expressions, such as:
{ 1 . 'foo' . 2 + 3 }.
which is equivalent to:
Array with: 1 with: 'foo' with: 2 + 3.
These arrays are created at runtime (as opposed to literal arrays) and are therefore safe to use. Your example again:
MyClass>>incrementedNumbers | numbers | numbers := { 1 . 2 . 3 . 4 . 5 . 6 . 7 . 8 }. "<====== " 1 to: numbers size: do: [:index | numbers at: index put: (numbers at: index) + 1]. ^ numbers
(Ab) using literal arrays
Sometimes there are reasons to actually mutate literal arrays (or, generally speaking, any method literal, to be frank). For example, if you have static information, such as images or binary data, that do not change at all, but are not always used, but you cannot (for any reason) use instance or class variables, you can save the object in an array of literals when first use:
MyClass>>staticInformation | holder | holder :=
Checking ifNil: will be true only at the first start of the method, subsequent executions will simply return the value that was returned by self generateBinaryData during the first call.
This scheme has been used by some structures for some time. However, in particular, for binary data, most Smalltalks (including Squeak and Pharo) now support a literal-byte array of the form #[ โฆ ] . Then this method can simply be written as
MyClass>>staticInformation ^