在GNU Smalltalk中导入文件

Tec*_*eer 5 import smalltalk gnu-smalltalk

我是GNU Smalltalk的新手.我知道在大多数编程语言中,有一个import/ #include/ require命令可以让一个源文件访问另一个源文件的内容.我的问题是,如何在GNU Smalltalk中将一个文件导入另一个文件?任何帮助,将不胜感激.谢谢!

ben*_*ers 6

我认为有两个很好的答案:

  1. FileStream fileIn: 'afile.st'.

  2. 在 GNU Smalltalk 中,您不会将一个源文件导入/包含/要求另一个源文件。

解释第一个答案

假设我有文件foo.st

"foo.st"
Object subclass: Foo [
    foo [^ 'I am Foo from foo.st']
]
Run Code Online (Sandbox Code Playgroud)

如果我想使用Foo我在里面编写的代码中的类bar.st,我可以FileStream fileIn: 'foo.st'在以下init方法中使用Bar

  "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.
    ]
]
Run Code Online (Sandbox Code Playgroud)

使用这些类看起来像:

$ 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'
Run Code Online (Sandbox Code Playgroud)

到目前为止,这一切看起来都像普通的导入/包含/要求。但这并不是真的,因为FileStream fileIn: 'foo.st'内部init发生 在运行时,所以我可以输入:

st> f := Foo new
a Foo
st> f foo
'I am Foo from foo.st'
Run Code Online (Sandbox Code Playgroud)

解释第二个答案

Foo导入后得到新的原因bar.st是因为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>
Run Code Online (Sandbox Code Playgroud)

现在我可以启动已经包含的图像Foo

$ gst -I foo.im
GNU Smalltalk ready

st> f := Foo new
a Foo
st> f foo
'I am Foo from foo.st'
Run Code Online (Sandbox Code Playgroud)

只要我不积极Foo并行开发Bar,我就可以将其更改init为:

init [
  barsFoo := Foo new.
]
Run Code Online (Sandbox Code Playgroud)

我还可以使用Foo和创建一个新图像Bar

$ gst -I foo.st
GNU Smalltalk ready

st> FileSteam fileIn: 'bar.st'
FileStream
st> ObjectMemory snapshot: 'foobar.im'
Run Code Online (Sandbox Code Playgroud)

从最新来源构建系统

可以创建一个从磁盘读取两个文件的最新版本的对象:

Object subclass: FooBarBuilder [
    FooBarBuilder class >> new [
        | r |
        r := super new.
        ^ r init.
    ]

    init [
        FileStream fileIn: 'foo.st'.
        FileStream fileIn: 'bar.st'.
    ]
]
Run Code Online (Sandbox Code Playgroud)

并构建一个图像:

$ gst
GNU Smalltalk ready

st> FileStream fileIn: 'foobarbuilder.st' 
FileStream
st> ObjectMemory snapshot: 'foobar.im'
"Global garbage collection... done"
false
st> 
Run Code Online (Sandbox Code Playgroud)

使用新图像foobar.im使我可以在每次创建新Foo的. 不太漂亮而且有点麻烦,但它可以完成真正构建系统的一些工作。BarFooBarBuilder

将其全部打包

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>
Run Code Online (Sandbox Code Playgroud)

下一步是“发布”该软件包,以便 GNU Smalltalk 可以使用 找到它gst-package。在这里,我将其发布到homeLinux 中的目录而不是系统范围的位置(/usr/share/gnu-smalltalk/在 Ubuntu 16.04 上):

~/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>
Run Code Online (Sandbox Code Playgroud)

结束语

天下没有免费的午餐。GNU Smalltalk 通过以熟悉的方式轻松处理文件而获得了一些好处。代价是文件与图像的抽象不能很好地集成,并且开发主要通过修改运行图像来进行。

天下没有免费的午餐。在某些时候,由于阻抗不匹配,传统 Smalltalk IDE 的收益可能会超过对源代码文件的熟悉程度。