Erlang的Eshell如何保持输入行不受异步输出的影响?

时间:2014-10-04 23:49:22

标签: erlang erl

我想用Erlang之外的另一种语言实现一个REPL,我真的对这个交互式erl(Eshell)提示的这个特性感兴趣:

1> spawn(fun() -> timer:sleep(5000), io:format("~p~n", ["later"]) end).
<0.34.0>
2> i can ty

所以我在这里做的是产生一些最终写入终端的后台进程。与此同时,我已经输入了i can ty,过了五秒钟,"later"被插入2>正上方,导致:

1> spawn(fun() -> timer:sleep(5000), io:format("~p~n", ["later"]) end).
<0.34.0>
"later"      
2> i can type...

在其他语言中,例如Bash或Node.js,这可能会产生类似的结果:

2> i can ty"later"
pe...

Erlang如何做到这一点?我试过谷歌搜索,甚至快速查看其源代码,但无法找到如何实现。我认为它必须涉及一些终端控制序列?

1 个答案:

答案 0 :(得分:4)

Erlang shell比其他语言更复杂,因为它必须与具有许多进程的分布式系统一起使用。 Fred Hebert撰写了关于Erlang shell的文章,名为&#34; As bad as anything else&#34;。

基本上,当您致电io:format时,它会向其组长发送消息。在&#34; Learn you some Erlang/Building OTP applications&#34; (再次由弗雷德),有一个关于组长和io protocol的说明。

正如@rightfold在评论中提到的那样,io_protocol涉及发送消息。这意味着,它们按顺序写入控制台。在其他语言中,如果您有更多进程同时写入,则可以将部分消息交错,但不能在Erlang中。该协议还涉及等待​​回复。例如,请检查io:execute_request on github

user_drv负责将消息写入实际的tty,并使用ncurses将消息放在其所需的位置,以便它可以在您开始编写的命令之前插入消息,这留下了干净的历史。