erLang学些笔记3–module

 

10. modules

终于要进入模块了。。。。。

所谓的模块就是将一些命令集合组织在一个模块中 。 其实在之前我们也已经接触到了一些modules .例如 head ,tail

 

1.核心模块的使用语法:Module:Function(Arguments).

 

1> erlang:element(2,{2,3,4}).     //取数组的第二个值
3
2> element(2,{a,b,c}).
b
3> lists:seq(1,5).
[1,2,3,4,5]
4> seq(1,5).
** exception error: undefined shell command seq/2

 

 

可以看到有些函数我们不需要制定 module,例如element,而有些必须制定Module.例如seq .这个同java中lang包下的API不需要引入包名,而其他包下的函数需要引入。

理论上来说,一个module一般是一些共同特性函数的集合。

 

2.模块的申明

一般来说 module包含两个部分:属性和函数

属性:是对这个module的描述,包含申明功能,是元数据。

函数:对外暴露的功能,可被外界访问。

 

3.写第一个自己的模块

 

首先 vim first.erl 进入vim编辑环境

我们声明这个是一个 module,就敲下一个行代码

 

3.1定义个了一个名字为first的module。方式基本同java。

 

-module(first).             //注意,最后面得这个.符号不能遗漏的,在erlang中是认为一个.作为一个命令行的结束。

 

 

3.2定义函数

 

add(A,B) -> A + B.         //定义了一个函数名为add。传递参数为 A,B的函数。注意中的变量必须要符合变量的定义规则!大写开头,小写的是atom

 

 

3.3 函数定义了,如何对外声明说我们定义了一个函数

 

-export([add/2]).          //export表示这个函数可以被外部访问add:函数名, 2代表这个函数传递的是两个参数。因为我们可以两个完全相同的函数名,但是参数不同,类似于java中的重载

 

 

好了一个完成的module已经完成了!完整代码如下所示:

 

-module(first).

-export([add/2]).

add(A,B) -> A + B.

 

 

3.4接下来就是module的编译了!

在命令行下可以使用 erlc flag file .具体的flag后面再表。 erlc first.erl 即可。

若是在erlang中的shell环境,使用 c(first).即可

编译后会生成一个 first.beam文件 类似java中的 class,共erlang的虚拟机解析

 

3.5看运行效果

 

1> cd('/home/inter12/work/erl').    //这个是进入这个module的执行目录
/opt/home/inter12/work/erl
ok
2> first:add(1,2).                //运行函数的方式就是 module:fun(arg,..)
3

 

 

4.较复杂的module

 

-module(first).
-export([add/2,hello/0,greet_and_add_two/1]).    //存在多个函数的话,声明方式的语法是 -export([Function1/Arity, Function2/Arity, ..., FunctionN/Arity]).

add(A,B) ->
 A + B.

%%show greeeting 
%%io format is the standard output text    这个是注释
hello() ->
 io:format("hello world~n").             //io 模块是编译器自动导入的module,format标准的输出函数

greet_and_add_two(X) ->                 // 函数中可以调用别的函数,不同函数间用逗号分隔即可!
  hello(),
  add(X,2).

 

 

注意点:在greet_and_add_two函数中调用 其他两个函数,没有进行import。是因为io是本身提供的函数,而add是在这个module中声明的,若是希望去调用些其他函数的需要进行导入。语法如下:

-import(Module, [Function1/Arity, …, FunctionN/Arity]).

 

看运行结果:

 

1> first:add(1,2).
3
2> first:hello().
hello world
ok                        //为什么这个地方会返回一个OK呢,因为erlang函数中若是执行没有问题的话,会返回一个ok字符串。若是数值运行的话则会将运算的结果进行返回!
3> first:greet_and_add_two(3).
hello world
5
4> first:greet_and_add_two(3,4).   //调用不存在的函数,则出错!
** exception error: undefined function useless:greet_and_add_two/2

 

 

 

在前面我提到了 erlc flag file 。具体由哪些flag呢,如下所示:

 

-debug_info
    Erlang tools such as debuggers, code coverage and static analysis tools will use the debug information of a module in order to do their work.
-{outdir,Dir}
    By default, the Erlang compiler will create the 'beam' files in the current directory. This will let you choose where to put the compiled file.
-export_all
    Will ignore the -export module attribute and will instead export all functions defined. This is mainly useful when testing and developing new code, but should not be used in production.
-{d,Macro} or {d,Macro,Value}
    Defines a macro to be used in the module, where Macro is an atom. This is more frequently used when dealing when unit-testing, ensuring that a module will only have its testing functions created and exported when they are explicitly wanted. By default, Value is 'true' if it's not defined as the third element of the tuple.

 

 

具体的使用如下。

 

1> c(first,[debug_info,export_all]).
2>compile:file(useless, [debug_info, export_all]).

 

 

5.关于module更多的信息

 

我们知道在编译为源码后,如何查看一些module的信息,包括module的一些属性信息。那么就可以如下命令了!

 

3> first:module_info().
[{exports,[{add,2},
           {hello,0},
           {greet_and_add_two,1},
           {module_info,0},
           {module_info,1}]},
 {imports,[]},
 {attributes,[{vsn,[170044895626526885037789809337737753350]}]},
 {compile,[{options,[debug_info,export_all]},
           {version,"4.6.4"},
           {time,{2011,8,10,7,9,24}},
           {source,"/opt/home/inter12/work/erl/useless.erl"}]}]

 

 

具体就不解释了!应该很容易看的明白!若是想了解具体某个信息,可用如下命令!

 

4> useless:module_info(exports).
[{add,2},
 {hello,0},
 {greet_and_add_two,1},
 {module_info,0},
 {module_info,1}]

 

 

若是想在module中加入作者的信息,可用

-author(“An Erlang Champ”)

-vsn是erlang编译器自动生成的标识 主要作用是在程序运行时,做到热部署。具体怎么做到还需要了解!

下面是添加 aythor后的代码

 

-module(useless).
-export([add/2,hello/0,greet_and_add_two/1]).
-author('zhaoming.xuezm').

add(A,B) ->
 A + B.

%%show greeeting 
%%io format is the standard output text 
hello() ->
 io:format("hello world~n").

greet_and_add_two(X) ->
  hello(),
  add(X,2).

 

 

编译后运行

 

3> useless:module_info(attributes).
[{vsn,[170044895626526885037789809337737753350]},
 {author,['zhaoming.xuezm']}]
module之间不要做循环依赖 A 依赖了 B ,但是B 中 这个方法又去依赖了 A 中的某个方法。函数式编程切忌的就些,这会造成后期很大的维护成本!

作者: inter12

在这苦短的人生中,追求点自己的简单快乐

发表评论

电子邮件地址不会被公开。 必填项已用*标注