分离计算部分
在一些程序里,我们可能希望将计算部分完全隔离出来,以免影响其它程序。Erlang shell就是这样一个东西。第??章那个简单的shell是有缺陷的。在它里面运行的一个表达式可能通过这几种方式影响到进程:
- 它可以发送进程标示符给其他进程(self/0),然后就可以与这个进程建立连接,给它发送消息。
- 它可以注册或注销一个进程程序8.1用另外一种方法实现了一个shell:
程序8.1
- -module(c_shell).
- -export([start/0, eval/2]).
- start() ->
- process_flag(trap_exit, true),
- go().
- go() ->
- eval(io:parse_exprs('-> ')),
- go().
- eval({form, Exprs}) ->
- Id = spawn_link(c_shell, eval, [self(), Exprs]),
- receive
- {value, Res, _} ->
- io:format("Result: ~w~n", [Res]),
- receive
- {'EXIT', Id, _ } ->
- true
- end;
- {'EXIT', Id, Reason} ->
- io:format("Error: ~w!~n", [Reason])
- end;
- eval(_) ->
- io:format("Syntax Error!~n", []).
- eval(Id, Exprs) ->
- Id ! eval:exprs(Exprs, []).
shell进程捕获EXIT信号。命令在一个与shell进程连接的单独的进程(spawn_link(c_shell,eval,[self(),Exprs]))中运行。尽管事实上我们把shell进程的进程ID给了c_shell:eval/2,但是因为对于作为实际执行者的eval:exprs/2函数,并没有给它任何参数,因此也就不会对造成影响。