snip.py来应付这些问题。给代码片段起个名字,比如下面这个例子中叫my-first-snippet,把代码片段写在% SNIP BEGIN和 % SNIP END之间,这样就可以根据名字来判断是不是同一个片段了。
% SNIP BEGIN my-first-snippet
hello() ->
world.
% SNIP END
运行snip.py build之后,这些注释都会被删掉,就变成下面这样。
hello() ->
world.
Erlang中还有一种特殊的情况,clause之间是用;分开的,但是最后一个clause结尾处用的是.。此时可以用%- SNIP END。这样build后,会把注释前后两行接成一行,不会出现;和.分别单独占一行的情况。比如下面这个例子中,在第一个文件里,只有一个clause。
% SNIP BEGIN my-second-snippet
hello(1) ->
world
%- SNIP END
.
运行snip.py build之后,就变成下面这样。
hello(1) ->
world.
在第二个文件里,有两个clause。
% SNIP BEGIN my-second-snippet hello(1) -> world %- SNIP END ; hello(2) -> big_world.运行
snip.py build之后,就变成下面这样。
hello(1) -> world; hello(2) -> big_world.因为恰好LaTeX和Erlang注释用的都是
%。可以在LaTeX文档里也可以用同样的记号。为了能在PDF里看到代码片段所在的文件名和行号,需要使用% SNIP REFERENCE。
% SNIP REFERENCE hello.erl my-first-snippet
\begin{SourceCode}
% SNIP BEGIN my-first-snippet
hello(1) ->
world.
% SNIP END
\end{SourceCode}
修改过代码后,运行snip.py status会列出所有不同步的代码片段的名字,接着就可以用snip.py sync来选择某个文件里的片段,把所有文件里的同名代码片段都修改成一样的。
\newcounter{erlangshellsession}[section] \newoutputstream{erlangshellsession} \newenvironment{ErlangShellSession}{ \stepcounter{erlangshellsession} \openoutputfile{\currfiledir\theerlangshellsession.session}{erlangshellsession} \writeverbatim{erlangshellsession} }{ \endwriteverbatim \closeoutputstream{erlangshellsession} \begin{SingleSpacing} \lstinputlisting[title={Erlang Shell}]{\currfiledir\theerlangshellsession.session} \end{SingleSpacing}}很糟糕的是,OTP并没有包含类似Python里的doctest的功能。Erlang作者之一,Joe Armstrong不久前也在Erlang Questions邮件列表上问如何实现类似的功能[1]。 Erlang Shell和一般的REPL在功能上有些出入,而且文档也不全。启动Shell的process,得先把自己设置成group leader,这样才能以I/O protocol与Shell通信。收到
get_until消息,那么就向Shell发送他想要的内容。收到put_chars消息,就把这些字符和记录去比较。假如所有记录内容都已经比较完了,也没有出现不同,那么就向Shell发送eof消息,等Shell退出。
| [1] | Programmatic interface to the shell |
| [1] |
When Perl 6 arrives, every day will be like Christmas!