3

我现在第三次遇到这个问题,你们中的一些 Squeak 程序员可能从屏幕截图中识别得最好:

在此处输入图像描述

这是重现问题的示例代码:

d:=Dictionary new.
(1 to: 257) do: [:each|
    d at: each put: each
].
f:=FileStream fileNamed: 'asdf.txt'.
d storeOn: f.
f reset.
d2:=Dictionary readFrom: f.
f close.

我知道它为什么会发生(编译器用于反序列化,它通过将整个文件放在一个方法中来实现)。

过去,我总是将代码更改为使用数据库或使用其他形式的序列化。但我想知道是否有某种方法可以修复 Squeak 以使其正常工作

4

2 回答 2

6

目前,没有适当的方法解决这个问题。

问题是,它CompiledMethod的格式是 VM 已知的,也是 VM 所期望的。这包括 256 个文字限制。更改方法格式需要更改虚拟机。这就是为什么人们直到现在都在犹豫改变字面限制的原因。

最近,人们花费了大量精力来创建一种新格式,不仅用于方法,而且完全改变了对象格式:SPUR 对象格式旨在增加方法中文字的数量,等等。

于 2013-10-16T14:54:39.897 回答
4

如图所示,#storeOn: API 不是强化的序列化 API。但是,如果您要使用它们(而不是每年左右来来往往的序列化项目之一),您可以与“聪明”(这是 256 字面限制是什么,这是一个优化的东西)进行斗争,有一些自己的“聪明”。

一个技巧是利用我们可能认为的“嵌套”文字没有限制。

a := #(1 2 3 4 5 6 7 8 9)

不包含 10 个文字。它只包含一个,即数组本身。它可以在其中包含任意数量的文字。因此,利用一点额外的Dictionary魔力,我们可以将您的示例更改为:

d := Dictionary new.
(1 to: 257) do: [:each | d at: each put: each].
f := FileStream fileNamed: 'asdf.txt'.
pairs := d associations collect: [:kv | Array with: kv key with: kv value ].
pairs storeOn: f.
f reset.
d2 := Dictionary newFromPairs: (Array readFrom: f).
f close.
d2

基本上,我们正在将您的字典变成一个数组数组。所以它只是你要存储的一种文字。然后我们使用了一个方便的工具newFromPairs:,它碰巧带了……鼓声……一个数组数组。

于 2013-10-17T21:01:25.760 回答