我记得mochiweb的源码里貌似使用过这种parameterized module.
虽然不知道erlang的底层实现,但感觉上就是个语法糖,
首先建立文件people_oo.erl
-module(people_oo, [Name, Age]).
这里的Name,Age的作用域相当于整个module,
这时查看people_oo:module_info(export):
[{new, 2}, {instance,2},{module_info,1}, {module_info,2}],
比这正常的module多了两个函数 new/2 instance/2,其实如果把这个module看成一个class,
这两个是用来初始化类对象的。(呃,这里姑且用类对象来称呼吧= =)这些导出的函数不就相当于类似静态方法了嘛……
现在我们添加以下代码,
-export([say_age/0,
say_name/0]).
say_age() ->
io:format("I was ~p years old.~n", [Age]).
say_name() ->
io:format("My name's ~p.~n", [Name]).
再次查看 export:
[{new, 2}, {instance,2}, {say_age,1}, {say_name,1}, {module_info,1}, {module_info,2}],
发现,又多出了两个函数,但有一个问题,我们的say_age和say_name的 arity明明是零啊,这里可以证明 erlang在底层对导出的函数做了一些处理,
我把它想象成往每个函数的第一个参数默认传递一个上下文指针进去(大概就是这么个意思,大家别对我的称呼太较真,实在找不到合适的称谓)
启发于lisp,我用closure实现了类似功能,
new(Name, Age) ->
[fun() -> io:format("My name's ~p.~n", [Name]) end,
fun() -> io:format("I was ~p years.~n", [Age]) end].
其实我觉得这才更适合FP的风格,
具体测试代码在这里:https://gitcafe.com/star/module_params_test
这里还有一个问题,使用parameterized module 的方式,类似module:method这种全限定调用函数的方法,有利于代码动态加载,
这点是直接使用闭包没办法做到,至于这些,过段时间我会写一些动态更新代码的文章,到时候再提及。