最近在看mochiweb的源代码时, 发现一个有趣的用法:
当一个http请求到达时:%% @spec new_request({Socket, Request, Headers}) -> MochiWebRequest %% @doc Return a mochiweb_request data structure. new_request({Socket, {Method, {abs_path, Uri}, Version}, Headers}) -> mochiweb_request:new(Socket, Method, Uri, Version, mochiweb_headers:make(Headers));
但mochweb_request却没有new 方法. 跟人请教了才知道, 这是erlang中的parameterized module
简单介绍一下parameterized module
一个简单的例子: 假设http server中acceptor 进程A 读取数据包后, 需要创建一个request 对象C, 携带请求的状态进入业务进程B中进行处理. parameterized module就是为了这样类似的需求而生的.
在module语句中使用如下格式: (A1, A2 为module的参数, 可以理解为面对对象编程中的饿对象的属性)
-module(ModuleName, [A1, A2, A3...])
M = name:new(A1, ..., An)
一个简单的server例子, 其中, 传入的参数Mod需要有init/1, handle/2 cleanup/1 三个方法.
为了减少出错, 例子中的Mode可以用一个abstract module约束, 也就是说顶一个behavior:
过度使用parameterized modules, 会导致代码中很多的M:f(Args), 导致代码可读性很差, 所以并不是非常建议过度使用.实际erlang编程中,我们也是非常厌恶看到一个M:F(Args)的, 毕竟是运行时的东西, 很难判断.
parameterized modules给erlang增添了一点儿OOP的味道. 有意思.
Reference: