> 
>> hi,
>> i have a testsuite that is a subclass of TestCase with this method:
>> 
>> testStupid
>> |a|
>> a :=#(1).
>> self assert: a first isNumber .
>> a :=a at:1 put: nil.
>> 
>> if i run the test once, it succeeds, but but when i run it a second time it 
>> fails. this seems to be sligthly counterintuitive, or how do i have to 
>> understand it?
> 
> 
> Interesting, I would never have guessed the test would be broken at first 
> sight. So maybe some people enlightened in the ways of the compiler can 
> provide a better explanation than me. Here is my guess:
> 
> #(1) is a special construct which creates a compile-time array. The 
> compile-time makes the trick: in short the array is more or less encoded 
> directly into the bytecodes of the method as a constant.
> But modifying the array with #at:put: directly modifies the bytecodes in the 
> compiled method itself. So you create a side-effect directly into your method.
> 
> Am I the only one to find this a bit dangerous and not intuitive? Is it a 
> well-known behavior?

It is clearly ugly.
Here what you see is a modification of the literal object that is stored in the 
compiled method literal 
frame. This is a well know limit of Smalltalk implementation. Having immutable 
literal objects may solve this problem.

You get the same if you modify a string since this is a container of characters.
This is like the optimization of similar literal strings that breaks the fact 
that 
        'foo' == 'foo' return false. 
normally yes this is false but when on the same method you get the same literal.



Stef

Reply via email to