[每日一Errr~lang] erlang shell
2010-02-26 09:30:34| 分类:
lang_erlang
| 标签:
|举报
|字号大中小 订阅
今天来说说 erl 这个 vm shell 的基本操作。
启动,并看看有啥命令可以用。
$ erl
Erlang R13B01 (erts-5.7.2) [source] [smp:2:2] [rq:2] [async-threads:0] [hipe] [kernel-poll:false]
Eshell V5.7.2 (abort with ^G)
1> help().
** shell internal commands **
b() -- display all variable bindings
e(N) -- repeat the expression in query <N>
f() -- forget all variable bindings
....
2>
erl 启动后,就相当于一个完整的 *nix 系统,里面已经跑着许多 erlang process 了。我们可通过下面几个指令察看进程信息。
i() -- information about the system
ni() -- information about the networked system
i(X,Y,Z) -- information about pid <X,Y,Z>
2> i().
Pid Initial Call Heap Reds Msgs Registered Current Function Stack
<0.0.0> otp_ring0:start/2 1597 2624 0 init init:loop/1 2
<0.2.0> erlang:apply/2 4181 146589 0 erl_prim_loader erl_prim_loader:loop/3 6
....
关于module
在 erlang 中,每个文件就是一个 module。可以通过 -module(mod_name). 来定义 module name,而文件名必须与module name 是一样的,此为强制要求。
在 erl shelll 中可通过 c() 指令来加在一个 module。
--------------------------------------------
-module(mymod).
-export([foo/0]).
foo() ->
io:format("I'm mymod 001.~n").
--------------------------------------------
$ erl
1> c(mymod). # mymod 这是个 atom,也可以写 c("mymod"). 则 "mymod" 是个 string
{ok,mymod}
2> mymod:foo().
I'm mymod 001.
--------------------------------------------
我们可以修改 mymod.erl 的内容,重新 c(mymod) 一下,则模块就更新了。
通过 m() 我们可以看到所有当前已加载的 module:
3> m().
Module File
application /usr/local/lib/erlang/lib/kernel-2.13.3/ebin/application.beam
...
mymod /home/kasicass/sandbox/erlang/shell/mymod.beam
...
module 与 erlang process
erlang 中,module 和 process 是两个不同的东西。module 相当于代码段,都加载好放在那。而我们程序可以启动多个 process,每个 process 执行着这些代码段。
看看下面的例子,我们通过 spawn 立即创建了一个 process。其中 fun() -> ... end 是匿名函数,erlang 也支持 upvalue 的哦。每个 process 有对应的 pid 就是下面的 <0.44.0>。通过 i(X,Y,Z) 可以查看process的详细信息。
---------------------------------------
4> P1 = spawn(fun() -> mymod:foo() end).
I'm mymod 001.
<0.44.0>
5> i(0,44,0).
undefined
---------------------------------------
为啥用 i(0,44,0) 找不到这个 process 呢?因为已经执行完毕,退出了。
我们修改下代码,让 process sleep 10秒。
---------------------------------------
-module(mymod).
-export([foo/0]).
foo() ->
io:format("I'm mymod 001.~n"),
timer:sleep(timer:seconds(10)),
io:format("I'm quit~n").
---------------------------------------
8> c(mymod).
{ok, mymod}
9> P1 = spawn(fun() -> mymod:foo() end).
I'm mymod 001.
** exception error: no match of right hand side value <0.60.0>
10> i(0,60,0).
[{current_function,{timer,sleep,1}},
{initial_call,{erlang,apply,2}},
{status,waiting},
...
{garbage_collection,[{fullsweep_after,65535},{minor_gcs,0}]},
{suspending,[]}]
I'm quit
---------------------------------------
BIF (build in function)
上面用到的 spawn 就是所谓的BIF啦。代码中为了更好的区分函数的来源,也会写成 erlang:spawn,其中 erlang: 是 BIF 的 module name。
MFA (module, function, args)
erlang 文档上经常会写 MFA,刚开始看,一下还不知道是啥玩意。我们调用 module 函数,都是
module_name:func_name(args)
其实等价于 apply(module_name, func_name, args)
---------------------------------------
13> apply(mymod, foo, [ ]).
I'm mymod 001.
I'm quit
ok
---------------------------------------
参数列表(Args)是通过一个 list [ ] 传入的。比如:
myfunc(Arg1, Arg2) -> ....
则应该
apply(mymod, myfunc, [Arg1, Arg2])
变量不能重复赋值(核心原则)
稍等~ 稍等~~,上面那里有个出错:
---------------------------------------
9> P1 = spawn(fun() -> mymod:foo() end).
I'm mymod 001.
** exception error: no match of right hand side value <0.60.0>
---------------------------------------
为啥呢?因为 P1 在之前已经被使用过了,看:
---------------------------------------
4> P1 = spawn(fun() -> mymod:foo() end).
I'm mymod 001.
<0.44.0>
---------------------------------------
erlang 称之 variable binding,就是 P1 这个变量已经被赋值了,不能再次赋值。
所以,所有变量在 erlang 中都是 copy-on-write 的,好处就是不会产生任何的 side-effect。如此这般,就带来了concurrency。
评论这张
转发至微博
转发至微博
评论