Thank your detailed explanation.<br>You do explain this old shell behavior in the book.<br><br>Best Regards!<br>James<br><div><span class="gmail_quote">2006/8/23, Joe Armstrong (TN/EAB) <<a href="mailto:joe.armstrong@ericsson.com">
joe.armstrong@ericsson.com</a>>:</span><blockquote class="gmail_quote" style="border-left: 1px solid rgb(204, 204, 204); margin: 0pt 0pt 0pt 0.8ex; padding-left: 1ex;"><div>
<div>
<div><font color="#0000ff" face="Arial" size="2"><span>Very
good question! </span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>Why
the program in the book works and why your program does not, depends upon the
behaviour</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>of the
Erlang shell.</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>The
Erlang shell used when the book was written and the Erlang shell in the current
Erlang distribution</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>work
differently - this difference invalidates the example in the
book.</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>When
the book was written the Erlang shell evaluated each new command in a
fresh</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>process. Today the shell appears to evaluate all
commands in a single evaluator process </span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>and
only restart the evaluator if it fails.</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>When
you evaluate</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>
link_demo:demonstrate_normal() </span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>in the
shell it merely creates a link to the demo process and do </span></font><font color="#0000ff" face="Arial" size="2"><span>nothing
else</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>so
there is no exit.</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>In the
old Erlang shell (the one used when we wrote the book)
link_demo:demonstrate_normal()</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>was
evaluated within a process (ie we spawn one process per shell command) - this
process</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>did
two things, it first evaluated the link(whereis(demo)) command linking itself to
demo</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span>then
it died - that is where the exit comes from.</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>To
emulate the old behaviour you can try this:</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span> >
link_demo:start()</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span>Then
</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"><span></span></font> </div>
<div><font color="#0000ff" face="Arial" size="2"><span> > spawn(fun() ->
link_demo:demonstrate_normal() end)</span></font></div>
<div><font color="#0000ff" face="Arial" size="2"></font> </div>
<div><span><font color="#0000ff" face="Arial" size="2">In
this case you *will* get the behaviour you expect.</font></span></div>
<div><span><font color="#0000ff" face="Arial" size="2"></font></span> </div>
<div><span><font color="#0000ff" face="Arial" size="2">/Joe</font></span></div>
<div><span><font color="#0000ff" face="Arial" size="2"></font></span> </div><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2">
</font><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2">
</font><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2"></font><font color="#0000ff" face="Arial" size="2"></font><br>
<blockquote style="border-left: 2px solid rgb(0, 0, 255); padding-left: 5px; margin-left: 5px; margin-right: 0px;">
<div dir="ltr" align="left" lang="en-us">
<hr>
<font face="Tahoma" size="2"><b>From:</b> <a href="mailto:owner-erlang-questions@erlang.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">owner-erlang-questions@erlang.org</a>
[mailto:<a href="mailto:owner-erlang-questions@erlang.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">owner-erlang-questions@erlang.org</a>] <b>On Behalf Of </b>lang
er<br><b>Sent:</b> den 22 augusti 2006 18:22<br><b>To:</b>
<a href="mailto:erlang-questions@erlang.org" target="_blank" onclick="return top.js.OpenExtLink(window,event,this)">erlang-questions@erlang.org</a><br><b>Subject:</b> trap_exit cannot trap signal
when exit/1 doesn't called explicitly<br></font><br></div></blockquote></div><div><span class="e" id="q_10d39d8e29531ebc_1">
<div></div>I run the example link_demo(page 103) in Erlang
book:<br><br><br>-module(link_demo).<br><br>%%<br>%% Include
files<br>%%<br><br>%%<br>%% Exported
Functions<br>%%<br>-export([start/0,demo/0,demonstrate_normal/0,<br>
demonstrate_exit/1, demonstrate_error/0,demonstrate_message/1]).
<br><br>%%<br>%% API Functions<br>%%<br><br>start()
-><br> register(demo, spawn(link_demo, demo,
[])).<br><br>demo() -><br> process_flag(trap_exit,
true),<br> demo1().<br><br>demo1()
-><br> receive <br>
{'EXIT', From, normal}
-><br>
io:format("Demo process received normal exit from ~w~n",
[From]),<br>
demo1();<br> {'EXIT', From, Reason}
-><br>
io:format("Demo process received exit signal ~w from ~w~n", [Reason, From]),
<br>
demo1();<br> finished_demo
-><br>
io:format("Demo finished ~n",
[]);<br> Other
-><br>
io:format("Demo process message ~w~n",
[Other]),<br>
demo1() <br> end.<br><br><br>%%<br>%% Local
Functions<br>%%<br><br>demonstrate_normal() -><br>
link(whereis(demo)).<br><br>demonstrate_exit(What) -><br>
link(whereis(demo)),<br>
exit(What).<br>demonstrate_message(What) -> <br> demo !
What.<br>demonstrate_error()-><br>
link(whereis(demo)),<br> 1 = 2.<br><br>-----------<br>After
start(), I call demonstrate_normal(), demo process should trap the
exit(normal) signal, but it doesn't, <br> and if I call
demonstrate_exit(normal) , demo do trap the exit(normal).<br><br>The only
difference between theses two situations is the exiting process call exit/1
explicitly. <br><br>Must I call exit before existing ? <br><br>My environment:
MacBook(Intel) <br>Erlang (BEAM) emulator version 5.5 [source]
[async-threads:0]<br><br>Eshell V5.5 (abort with ^G)<br>1>
<br><br>Thanks!<br>Best Regards<br>James<br></span></div><div></div>
</div></blockquote></div><br>