我认为有两个很好的答案:
FileStream fileIn: 'afile.st'.
在 GNU Smalltalk 中,您不需要将一个源文件导入/包含/要求到另一个源文件中。
解释第一个答案
假设我有文件foo.st:
"foo.st"
Object subclass: Foo [
foo [^ 'I am Foo from foo.st']
]
如果我想使用我在bar.st 内部编写的代码中的Foo 类,我可以在init 的init 方法中使用FileStream fileIn: 'foo.st':
"bar.st"
Object subclass: Bar [
| barsFoo |
Bar class >> new [
| r |
r := super new.
^ r init.
]
init [
"Combines the contents of foo.st with the current image
and assigns a new Foo to barsFoo."
FileStream fileIn: 'foo.st'.
barsFoo := Foo new.
]
bar [
^ 'I am bar from bar.st'
]
foo [
^ barsFoo foo.
]
]
使用这些类看起来像:
$ gst
GNU Smalltalk ready
st> FileStream fileIn: 'bar.st'
FileStream
st> b := Bar new
a Bar
st> b foo
'I am Foo from foo.st'
到目前为止,这一切看起来就像一个普通的导入/包含/要求。但这并不是因为init 中的FileStream fileIn: 'foo.st' 发生在运行时,所以我可以输入:
st> f := Foo new
a Foo
st> f foo
'I am Foo from foo.st'
解释第二个答案
我在导入bar.st 后得到一个新的Foo 是因为FileStream fileIn: 'bar.st' 将bar.st 的内容与当前的图像结合在一起。
尽管 GNU Smalltalk 使用源代码文件的抽象。 Smalltalk 的底层抽象是图像而不是文件,这对于 GNU Smalltalk 和任何其他 Smalltalk 系统一样真实。缺少传统 IDE 并不会改变映像的首要地位。对我来说,作为一个新的 Smalltalk 用户,尤其是一个新的 GNU Smalltalk 用户,这是一个很难理解的抽象。
这意味着管理Bar对Foo的依赖的普通低级逐步方法是首先创建一个已经包含Foo的图像:
$ gst
GNU Smalltalk ready
st> FileStream fileIn: 'foo.st'
FileStream
st> ObjectMemory snapshot: 'foo.im'
"Global garbage collection... done"
false
st>
现在我可以启动已经包含Foo的图像了:
$ gst -I foo.im
GNU Smalltalk ready
st> f := Foo new
a Foo
st> f foo
'I am Foo from foo.st'
只要我不积极开发 Foo 与 Bar 我可以将其 init 更改为:
init [
barsFoo := Foo new.
]
我还可以使用Foo 和Bar 创建一个新图像:
$ gst -I foo.st
GNU Smalltalk ready
st> FileSteam fileIn: 'bar.st'
FileStream
st> ObjectMemory snapshot: 'foobar.im'
从最新源构建系统
可以创建一个从磁盘读取两个文件的最新版本的对象:
Object subclass: FooBarBuilder [
FooBarBuilder class >> new [
| r |
r := super new.
^ r init.
]
init [
FileStream fileIn: 'foo.st'.
FileStream fileIn: 'bar.st'.
]
]
并建立一个图像:
$ gst
GNU Smalltalk ready
st> FileStream fileIn: 'foobarbuilder.st'
FileStream
st> ObjectMemory snapshot: 'foobar.im'
"Global garbage collection... done"
false
st>
使用新图像foobar.im 允许我在每次创建新FooBarBuilder 时引入最新版本的Foo 和Bar。不是很漂亮而且有点笨拙,但它会完成一些真正的构建系统的工作。
全部打包
可以使用 GNU Smalltalk 的包系统将所有必要的文件导入“干净”的 Smalltalk 运行时,而不是跟踪多个图像(foo.im、foobar.im)。首先创建一个package.xml 文件:
<package>
<name>FileImport</name>
<file>foo.st</file>
<file>bar.st</file>
<file>foobarbuilder.st</file>
<filein>foo.st</filein>
<filein>bar.st</filein>
<filein>foobarbuilder.st</filein>
</package>
下一步是“发布”包,以便 GNU Smalltalk 可以使用 gst-package 找到它。在这里,我将它发布到我在 Linux 中的 home 目录而不是系统范围的位置(Ubuntu 16.04 上的 /usr/share/gnu-smalltalk/):
~/smalltalk/fileimport$ gst-package -t ~/.st package.xml
~/smalltalk/fileimport$ gst
GNU Smalltalk ready
st> PackageLoader fileInPackage: 'FileImport'
"Global garbage collection... done"
Loading package FileImport
PackageLoader
st> Foo new
a Foo
st>
结束语
没有免费的午餐。 GNU Smalltalk 通过以熟悉的方式轻松处理文件而有所收获。代价是文件与 images 的抽象并没有很好地集成,并且期望开发主要通过修改运行的图像来进行。
没有免费的午餐。在某些时候,由于阻抗不匹配,传统 Smalltalk IDE 的收益可能会超过使用源代码文件的熟悉度。