smalltalkgnu-smalltalk

Why is assigning many variables seem to mutate my variable?


I'm new to Smalltalk so I don't know if I'm doing something wrong but this seems very weird and buggy.

dict := Dictionary new.
dict at: 1 put: 1.
dict at: 2 put: 2.
dict at: 3 put: 3.
dict at: 4 put: 4.


1 to: 4 do: [:j |

  key := j.

  value := dict at: key.
  value print.

  value printNl.
].

This code works fine and correctly print

11
22
33
44

But then, if I add enough assignments to other variables the result of the script change:

dict := Dictionary new.
dict at: 1 put: 1.
dict at: 2 put: 2.
dict at: 3 put: 3.
dict at: 4 put: 4.


1 to: 4 do: [:j |

  key := j.

  value := dict at: key.
  value print.


  unrelated := 1.
  unrelated2 := 1.
  unrelated3 := 1.
  unrelated4 := 1.
  unrelated5 := 1.
  unrelated6 := 1.
  unrelated7 := 1.
  unrelated8 := 1.
  unrelated9 := 1.
  unrelated10 := 1.

  value printNl.

].

This code now prints

11
21
31
41

If I remove the line assigning unrelated10 it works again... Am I missing something or is GNU Smalltalk buggy ?

I am using GNU Smalltalk version 3.2.5.


Solution

  • I believe that this is a bug in GNU Smalltalk. It appears that the system allows you to reference variables that have not been defined (this "feature" is not standard) and the system's attempt to define the variables and their scope is having problems.

    The work-around is to define your own variables and give them as narrow a scope as possible (this is good practice in any language). So, try the following (validated at here):

    | dict |
    dict := Dictionary new.
    dict at: 1 put: 1.
    dict at: 2 put: 2.
    dict at: 3 put: 3.
    dict at: 4 put: 4.
    
    
    1 to: 4 do: [:j |
      "The following is a list of variables used in this code block"
      | key value 
        unrelated unrelated2 unrelated3 unrelated4 unrelated5
        unrelated6 unrelated7 unrelated8 unrelated9 unrelated10 |
         
      key := j.
    
      value := dict at: key.
      value print.
    
      unrelated := 1.
      unrelated2 := 1.
      unrelated3 := 1.
      unrelated4 := 1.
      unrelated5 := 1.
      unrelated6 := 1.
      unrelated7 := 1.
      unrelated8 := 1.
      unrelated9 := 1.
      unrelated10 := 1.
    
      value printNl.
    ].