Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What's the difference between the Array and Literal Array in Smalltalk?

Besides the size.

For example:

|arr|. arr := Array new: 10

and

#(element1,element2, ...)
like image 584
hogolyo Avatar asked Feb 10 '17 13:02

hogolyo


2 Answers

In both forms the object created is going to be of the same type and with the same elements. The main difference is that while using Array with: you get a new instance each time the code is executed, with the #( ) you get the instance created when the method is accepted/compiled, so that each time the code is executed the instance of the array is the same.

Consider the following code:

doSomething
    array := #(6 7 8).
    Transcript show: array.
    array at: 1 put: 3.

the first time you execute doSomething everything will be normal. The second time you will get 3, 7, 8 printed, because the array is the same that was modified the previous time the method was invoked.

So, you should be careful when using literals, and mainly leave them for cases where they are not going to be mutated.

like image 175
melkyades Avatar answered Nov 03 '22 09:11

melkyades


Consider this method in an example class with an instance variable threshold:

Example >> #threshold
    ^threshold
Example >> #threshold: anInteger
    threshold := anInteger
Example >> #initialize
    threshold := 0
Example class >> #new
    ^super new initialize

Example >> testArraySum
   | a |
   a := #(4 8 10).
   a sum > threshold ifTrue: [ a at: 1 put: a first - 2 ].
   ^a sum

Now, if you read the code of testArraySum, if threshold doesn´t change, it should always retunr the same, shouldn´t it? Becasue you start setting a fixed value to a, then subtract (or not, depending on threshold, but we said it was fixed) a fixed amount, so it should be... 20.

Well, if you evaluate

Example new testArraySum

several times, you will get 20,18, 16... because the array #(4 8 10) gets modified. On the other hand,

Example >> testConstantArraySum
   | a |
   a := Array new:  3.
   a at: 1 put: 4; at: 2 put: 8; at: 3 put: 10.
   a sum > threshold ifTrue: [ a at: 1 put: a first - 2 ].
   ^a sum

is really constant.

like image 24
Carlos E. Ferro Avatar answered Nov 03 '22 07:11

Carlos E. Ferro