Swift REPL:如何保存/加载REPL状态?(也称为挂起/恢复,快照,克隆)

5
在Swift REPL中,有什么方法可以保存REPL状态?
例如,我想在REPL中完成一些工作,然后将其保存,以便稍后加载。
这个概念可能被命名为save/load、suspend/resume、snapshot/clone、serialize/deserialize等。
任何能让我朝着这个目标前进的解决方案都会有所帮助,即使它像以下这些hack一样:
- 记录所有历史行,然后在另一个REPL中重放它们。 - 序列化所有对象,然后在另一个REPL中反序列化它们。 - 快照RAM或VM,然后将其克隆到另一台机器上。 - 保存全局状态的核心映像,然后稍后执行它。
我的目标是在一台机器上保存REPL工作,然后在另一台机器上加载它。
我只需要最终状态;我不需要堆栈、历史记录、句柄等。
XCode Playgrounds具有类似的功能,使用“Save”来外部化内容。

我怀疑Swift是否支持这个(而这种情况通常确实需要支持)。如果REPL在具有睡眠支持的VM中运行...但遗憾的是,这样的“镜像”使SmallTalk几乎成为独一无二的。我也不知道是否有基于进程的快照工具,但我没有查看过。 - user2864740
为什么不使用Playground? - user1375096
@huocp 因为Swift REPL非常棒 - 根据我的经验,它比playground更快速和轻量级。 - joelparkerhenderson
2个回答

3
也许这能对你有所帮助。
其实我刚发现Swift REPL会把当前的会话保存在一个文件中。
在REPL中键入__FILE__,你将会看到该会话文件。
  1> __FILE__
$R0: String = "/var/folders/6j/xs_0g88d55dgprjrwdws898w0000gn/T/lldb/3869/repl1.swift"

您可以查看文件内容,它会跟踪当前的 REPL 会话。

我相信您可以构建一行 Swift 代码将该文件复制到您的保存文件夹中,在会话结束时运行该代码。

顺便说一句,在临时文件夹中,repl.swift 实际上比 repl1.swift 更紧凑。您可能想要复制 repl.swift


谢谢!Swift REPL 似乎在 FILE 目录中创建了许多文件。每个 REPL 命令似乎都会创建两个文件:一个 .swift 文件和一个 .cpp 文件。没有一个没有数字的 .swift 文件(“repl.swift”)似乎正在跟踪所有成功执行的 REPL 行。似乎没有办法将其重放到新的 REPL 中 - 我将尝试找到下一个方法。 - joelparkerhenderson
处理文件以过滤掉所有注释,然后将剩下的内容传递到 Swift 的调用中怎么样? - algal
2
这在Swift 3.1中不再起作用。__FILE__已经更名为#file,并且它只会输出repl.swift。但是,您可以使用find /var/folders/ -name repl.swift并查找匹配项。 - Palle

1
你可以尝试使用经典的命令行工具expectexpect会重放一个基于文本的交互脚本,并监视预期的响应。当然,这需要您编写一个expect脚本。
但是,如果您从软件包管理器(如MacPorts)安装expect,它还将安装命令autoexpect,该命令可以监视您的按键操作并自动生成一个expect脚本。
例如,您可以执行以下操作:
  autoexpect -f myscript swift

然后在repl上进行交互,完成后退出。稍后您可以执行以下操作

  ./myscript

然后它将重放该会话。

问题是?autoexpect将生成一个包含关闭REPL的最终命令的脚本。我不确定是否有一种方法可以运行脚本,以便省略该命令,并将控制权交给您。

这似乎正是这些实用程序最初设计的东西,因此如果功能不存在,我会感到惊讶。

其他类似的命令包括scriptinteract


1
这是一个非常好的通用答案,因为expect命令和script命令在许多其他目标中非常有用 - 感谢您向我介绍它们! - joelparkerhenderson

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接