• 分离计算部分

    分离计算部分

    在一些程序里,我们可能希望将计算部分完全隔离出来,以免影响其它程序。Erlang shell就是这样一个东西。第??章那个简单的shell是有缺陷的。在它里面运行的一个表达式可能通过这几种方式影响到进程:

    • 它可以发送进程标示符给其他进程(self/0),然后就可以与这个进程建立连接,给它发送消息。
    • 它可以注册或注销一个进程程序8.1用另外一种方法实现了一个shell:

    程序8.1

    1. -module(c_shell).
    2. -export([start/0, eval/2]).
    3.  
    4. start() ->
    5. process_flag(trap_exit, true),
    6. go().
    7.  
    8. go() ->
    9. eval(io:parse_exprs('-> ')),
    10. go().
    11.  
    12. eval({form, Exprs}) ->
    13. Id = spawn_link(c_shell, eval, [self(), Exprs]),
    14. receive
    15. {value, Res, _} ->
    16. io:format("Result: ~w~n", [Res]),
    17. receive
    18. {'EXIT', Id, _ } ->
    19. true
    20. end;
    21. {'EXIT', Id, Reason} ->
    22. io:format("Error: ~w!~n", [Reason])
    23. end;
    24.  
    25. eval(_) ->
    26. io:format("Syntax Error!~n", []).
    27.  
    28. eval(Id, Exprs) ->
    29. Id ! eval:exprs(Exprs, []).

    shell进程捕获EXIT信号。命令在一个与shell进程连接的单独的进程(spawn_link(c_shell,eval,[self(),Exprs]))中运行。尽管事实上我们把shell进程的进程ID给了c_shell:eval/2,但是因为对于作为实际执行者的eval:exprs/2函数,并没有给它任何参数,因此也就不会对造成影响。