Squeak Smalltalk数组中的奇怪行为

Squeak Smalltalk数组中的奇怪行为,smalltalk,squeak,Smalltalk,Squeak,我只是被以下行为绊倒了。要复制它,请使用inst var创建一个类: Object subclass: #Asdf instanceVariableNames: 'countSeq' classVariableNames: '' poolDictionaries: '' category: 'Asdf' 还有一个懒惰的init getter: countSeq ^countSeq ifNil: [ countSeq:=#(0) asOrderedCollection.

我只是被以下行为绊倒了。要复制它,请使用inst var创建一个类:

Object subclass: #Asdf
  instanceVariableNames: 'countSeq'
  classVariableNames: ''
  poolDictionaries: ''
  category: 'Asdf'
还有一个懒惰的init getter:

countSeq
^countSeq ifNil: [
  countSeq:=#(0) asOrderedCollection.
  countSeq at: 1 put: (countSeq at: 1)+1.
  countSeq
].
这是正确的。当我调用
Asdf new countSeq
时,它每次都返回
一个OrderedCollection(1)

但是,如果我删除了
asOrderedCollection

countSeq
^countSeq ifNil: [
  countSeq:=#(0).
  countSeq at: 1 put: (countSeq at: 1)+1.
  countSeq
].
并多次调用
Asdf new countSeq
,然后我得到
(1)
(2)
(3)
。 这怎么解释呢


(在我看来,这个数组的行为就像一个C静态局部变量。事实上,我尝试过:重新编译该方法,不幸的计数器再次从1开始)

这是因为文字数组
#(0)
存储在method对象中


此处解释:

是的,这确实是语言的陷阱。我在他参考的页面上对托拜厄斯的答案投了赞成票,建议大家彻底阅读。@BerndElkemann这不是语言的陷阱,而是由对象组成的系统的结果。一旦我们的OO思维克服了基于文本的推理,这种行为就会变得自然。一些方言(视觉作品)已经禁止这种行为。修改文字是一件坏事,我们可能在不久的将来禁止在Squeak中这样做(这在Spur VM中是可能的)。@LeandroCaniglia在语言设计中有两个很好的选择:(1)文字应该是不可变的,或者(2)文字应该被认为是“生成对象”(而不是“作为对象”)。(Smalltalk中“文字是对象”的原因是历史性的,不是很好。例如,我永远不会问数组“您使用的是哪种方法?”)在链接的问题中可以看到Tobias和Blablabla999的答案