Erlang 开端:将函数从脚本移至 OTP
Erlang beginnings: moving a function from an escript into OTP
'escript'in the Erlang docs 中有阶乘函数的简单实现。阶乘函数为:
fac(0) -> 1;
fac(N) -> N * fac(N-1).
没关系,我可以让它工作,没问题。
不过,我想知道如何使用 rebar3
在 'OTP way' 中实现同样的简单阶乘函数?
澄清一下,我的问题是:
- 代码去哪儿了?
- 如何从 shell 调用它?
- 我也可以像通过 escript 示例那样从命令行 运行 它吗?
仅供参考,我已经开始使用 rebar3
。这是我所在的位置:
rebar3 new app factorial
创建了一些文件,但具体代码位于 src
目录中的 3 个文件中。我可以看到正在使用主管,看起来不错。
我可以从 shell:
与这个项目互动
$ rebar3 shell
1> application:which_applications().
[{factorial,"An OTP application","0.1.0"},
{inets,"INETS CXC 138 49","7.0.3"},
{ssl,"Erlang/OTP SSL application","9.1.1"},
{public_key,"Public key infrastructure","1.6.4"},
{asn1,"The Erlang ASN1 compiler version 5.0.8","5.0.8"},
{crypto,"CRYPTO","4.4"},
{stdlib,"ERTS CXC 138 10","3.7"},
{kernel,"ERTS CXC 138 10","6.2"}]
2> application:stop(factorial).
=INFO REPORT==== 21-Jan-2019::12:42:07.484244 ===
application: factorial
exited: stopped
type: temporary
ok
3> application:start(factorial).
ok
代码去哪儿了?
到'call code in the OTP way',可以放在后面一个gen_server
.
对于这个简单的阶乘函数,我在 src
目录中添加了一个新文件 factorial.erl
,它几乎是一个标准的 gen_server
框架,我的阶乘函数作为回调之一:
% factorial.erl
-module(factorial).
-behaviour(gen_server).
-export([start_link/0, stop/0, calc/1]).
<boilerplate gen_server stuff here, like init, etc.>
calc(N) ->
{ok, Result} = gen_server:call(?SERVER, {calc, N}),
{ok, Result}.
handle_call({calc, N}, _From, State) ->
Factorial = factorial(N),
Reply = {ok, Factorial},
{reply, Reply, State};
factorial(0) ->
1;
factorial(N) ->
N * factorial(N-1).
因为我的 rebar3 new app factorial
创建了一个主管,我修改了主管的 init
以便它调用我的 factorial
模块:
% factorial_sup.erl
<skeleton supervisor stuff here>
init([]) ->
Server = {factorial, {factorial, start_link, []},
permanent, 2000, worker, [factorial]},
Children = [Server],
RestartStrategy = {one_for_one, 0, 1},
{ok, {RestartStrategy, Children}}.
如何从 shell 调用它?
$ rebar3 shell
<Enter>
1> factorial:calc(5).
{ok,120}
由于这是 运行 在主管之下,我们仍然可以停止并重新启动它:
2> application:stop(factorial).
=INFO REPORT==== 22-Jan-2019::13:31:29.243520 ===
application: factorial
exited: stopped
type: temporary
ok
3> factorial:calc(5).
** exception exit: {noproc,{gen_server,call,[factorial,{calc,5}]}}
in function gen_server:call/2 (gen_server.erl, line 215)
in call from factorial:calc/1 (/Users/robert/git/factorial/src/factorial.erl, line 32)
4> application:start(factorial).
ok
5> factorial:calc(5).
{ok,120}
如何创建可执行文件?
工作进行中:-)
。
'escript'in the Erlang docs 中有阶乘函数的简单实现。阶乘函数为:
fac(0) -> 1;
fac(N) -> N * fac(N-1).
没关系,我可以让它工作,没问题。
不过,我想知道如何使用 rebar3
在 'OTP way' 中实现同样的简单阶乘函数?
澄清一下,我的问题是:
- 代码去哪儿了?
- 如何从 shell 调用它?
- 我也可以像通过 escript 示例那样从命令行 运行 它吗?
仅供参考,我已经开始使用 rebar3
。这是我所在的位置:
rebar3 new app factorial
创建了一些文件,但具体代码位于 src
目录中的 3 个文件中。我可以看到正在使用主管,看起来不错。
我可以从 shell:
与这个项目互动$ rebar3 shell
1> application:which_applications().
[{factorial,"An OTP application","0.1.0"},
{inets,"INETS CXC 138 49","7.0.3"},
{ssl,"Erlang/OTP SSL application","9.1.1"},
{public_key,"Public key infrastructure","1.6.4"},
{asn1,"The Erlang ASN1 compiler version 5.0.8","5.0.8"},
{crypto,"CRYPTO","4.4"},
{stdlib,"ERTS CXC 138 10","3.7"},
{kernel,"ERTS CXC 138 10","6.2"}]
2> application:stop(factorial).
=INFO REPORT==== 21-Jan-2019::12:42:07.484244 ===
application: factorial
exited: stopped
type: temporary
ok
3> application:start(factorial).
ok
代码去哪儿了?
到'call code in the OTP way',可以放在后面一个gen_server
.
对于这个简单的阶乘函数,我在 src
目录中添加了一个新文件 factorial.erl
,它几乎是一个标准的 gen_server
框架,我的阶乘函数作为回调之一:
% factorial.erl
-module(factorial).
-behaviour(gen_server).
-export([start_link/0, stop/0, calc/1]).
<boilerplate gen_server stuff here, like init, etc.>
calc(N) ->
{ok, Result} = gen_server:call(?SERVER, {calc, N}),
{ok, Result}.
handle_call({calc, N}, _From, State) ->
Factorial = factorial(N),
Reply = {ok, Factorial},
{reply, Reply, State};
factorial(0) ->
1;
factorial(N) ->
N * factorial(N-1).
因为我的 rebar3 new app factorial
创建了一个主管,我修改了主管的 init
以便它调用我的 factorial
模块:
% factorial_sup.erl
<skeleton supervisor stuff here>
init([]) ->
Server = {factorial, {factorial, start_link, []},
permanent, 2000, worker, [factorial]},
Children = [Server],
RestartStrategy = {one_for_one, 0, 1},
{ok, {RestartStrategy, Children}}.
如何从 shell 调用它?
$ rebar3 shell
<Enter>
1> factorial:calc(5).
{ok,120}
由于这是 运行 在主管之下,我们仍然可以停止并重新启动它:
2> application:stop(factorial).
=INFO REPORT==== 22-Jan-2019::13:31:29.243520 ===
application: factorial
exited: stopped
type: temporary
ok
3> factorial:calc(5).
** exception exit: {noproc,{gen_server,call,[factorial,{calc,5}]}}
in function gen_server:call/2 (gen_server.erl, line 215)
in call from factorial:calc/1 (/Users/robert/git/factorial/src/factorial.erl, line 32)
4> application:start(factorial).
ok
5> factorial:calc(5).
{ok,120}
如何创建可执行文件?
工作进行中:-)
。