2

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ちょうど 5 秒が経過したところで入力したところ、 の"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 はどのようにそれを行うのでしょうか? 私はググってみたり、そのソースコードをざっと見たりしましたが、これがどのように達成されるかを見つけることができませんでした. いくつかの端末制御シーケンスが含まれている必要があると思いますか?

4

1 に答える 1

4

Erlang シェルは、多くのプロセスを持つ分散システムで動作する必要があるため、他の言語よりも複雑です。Fred Hebert は、Erlang シェルについて、" As bad as anything other "という記事を書きました。

基本的に、 を呼び出すとio:format、グループ リーダーにメッセージが送信されます。" Learn you some Erlang/Building OTP applications " (再び Fred によるもの) には、グループ リーダーとio プロトコルに関するメモがあります。

@rightfold のコメントで言及されているように、io_protocolメッセージの送信が含まれます。つまり、それらはコンソールに順番に書き込まれます。他の言語では、同時に書き込みを行うプロセスが多い場合、メッセージの一部をインターリーブできますが、Erlang ではできません。プロトコルには、応答の待機も含まれます。たとえば、io:execute_request github を確認してください。

user_drvメッセージを実際に書き込む責任があり、必要な場所に配置するためttyに使用ncursesするため、書き込みを開始したコマンドの前にメッセージを挿入でき、クリーンな履歴が残ります。

于 2014-10-05T07:10:44.970 に答える