%
% Program 7.3, Concurrent Programming in Erlang by J. Armstrong et al.
%
-module(link_demo).
-export([start/0, demo/0, demonstrate_normal/0, demonstrate_exit/1, 
	 demonstrate_error/0, demonstrate_message/1]).

start() ->
    register(demo, spawn(link_demo, demo, [])).

demo() ->
    process_flag(trap_exit, true),
    demo1().

demo1() ->
    receive
	{'EXIT', From, normal} ->
	    io:format(
	      "Demo process received normal exit from ~w~n",
	      [From]),
	    demo1();
	{'EXIT', From, Reason} ->
	    io:format(
	      "Demo process received exit signal ~w from ~w~n",
	      [Reason, From]),
	    demo1();
	finished_demo ->
	    io:format("Demo finished ~n", []);
	Other ->
	    io:format("Demo process message ~w~n", [Other]),
	    demo1()
    end.

demonstrate_normal() ->
    link(whereis(demo)).

demonstrate_exit(What) ->
    link(whereis(demo)),
    exit(What).

demonstrate_message(What) ->
    demo ! What.

demonstrate_error() ->
    link(whereis(demo)),
    1 = 2.

%%
%% Use, e.g., as follows:
%%
%% > c(link_demo).
%% link_demo.erl:46: Warning: no clause will ever match
%% {ok,link_demo}
%% > link_demo:start().
%% true
%% > link_demo:demonstrate_normal().
%% true
%% > link_demo:demonstrate_exit(bye).
%% Demo process received exit signal {bye,[{link_demo,demonstrate_exit,1,[{file,[108,105,110,107,95,100,101,109,111,46,101,114,108]},{line,39}]},{erl_eval,do_apply,6,[{file,[101,114,108,95,101,118,97,108,46,101,114,108]},{line,673}]},{shell,exprs,7,[{file,[115,104,101,108,108,46,101,114,108]},{line,686}]},{shell,eval_exprs,7,[{file,[115,104,101,108,108,46,101,114,108]},{line,641}]},{shell,eval_loop,3,[{file,[115,104,101,108,108,46,101,114,108]},{line,626}]}]} from <0.123.0>
%% Demo process received normal exit from <0.123.0>
%% ** exception exit: bye
%%      in function  link_demo:demonstrate_exit/1 (link_demo.erl, line 39)
%% > link_demo:demonstrate_exit(normal).
%% Demo process received normal exit from <0.137.0>
%% ** exception exit: normal
%% > link_demo:demonstrate_error().
%% Demo process received exit signal {{badmatch,2},[{link_demo,demonstrate_error,0,[{file,[108,105,110,107,95,100,101,109,111,46,101,114,108]},{line,46}]},{erl_eval,do_apply,6,[{file,[101,114,108,95,101,118,97,108,46,101,114,108]},{line,673}]},{shell,exprs,7,[{file,[115,104,101,108,108,46,101,114,108]},{line,686}]},{shell,eval_exprs,7,[{file,[115,104,101,108,108,46,101,114,108]},{line,641}]},{shell,eval_loop,3,[{file,[115,104,101,108,108,46,101,114,108]},{line,626}]}]} from <0.139.0>
%% Demo process received normal exit from <0.139.0>
%% ** exception error: no match of right hand side value 2
%%      in function  link_demo:demonstrate_error/0 (link_demo.erl, line 46)
%% > link_demo:demonstrate_message(hello).
%% Demo process message hello
%% hello
%% > link_demo:demonstrate_message(finished_demo).
%% Demo finished 
%% finished_demo
%% > link_demo:demonstrate_message(hello).
%% ** exception error: bad argument
%%      in function  link_demo:demonstrate_message/1 (link_demo.erl, line 42)
