代码改变世界

mochiweb 源码阅读(四)

2012-07-17 00:19  rhinovirus  阅读(2052)  评论(0编辑  收藏  举报

  大家好,最近Erlang社区好像又火起来了。这里推荐坚强2002同学推荐的Erlang QA站点,这里也顺便推荐给大家,地址:http://langref.org/erlang,也希望大家有问题,可以到上面去留言解决。当然也可以到成立涛创建的Erlang问答,地址:http://erlangqa.com/,也希望对Erlang有兴趣的朋友加入到Erlang社区,为更多人学习Erlang来提供帮助。

  好了,回到正题,上一篇我们还没讲完,这篇我们继续看,上一篇,讲到下面这个代码处:

    lists:filter(fun filelib:is_dir/1,
                 lists:append([[filename:join([X, "ebin"]),
                                filename:join([X, "include"])] ||
                                  X <- Siblings])).

  从上一篇,我们知道:

  < Siblings = ["/home/administrator/workplace/mochiweb_example/deps/mochiweb"]

  我们在shell上测试下上面函数的作用:

  

  这里有三个函数,之前应该是没有接触过,但是也很简单,我们来看下。

  函数:filelib:is_dir/1,erlang doc 地址:http://www.erlang.org/doc/man/filelib.html#is_dir-1,如下图:

  从文档上描述来看,还是挺简单的,如果Name为一个目录则返回true,否则返回false。

  函数:lists:append/1,地址:http://www.erlang.org/doc/man/lists.html#append-1,如下图:

  返回一个由所有的子列表项拼接而成的列表。

  函数:lists:filter/2,地址:http://www.erlang.org/doc/man/lists.html#filter-2,如下图:

   这个函数也很简单,List2是一个列表,它所有的元素都是List1的元素调用Pred(Elem)返回true的元素。

  好了,搞清楚这些系统函数的作用。也知道了mochiweb_example_deps:new_siblings/1 函数返回值:

  ["/home/administrator/workplace/mochiweb_example/deps/mochiweb/ebin",

  "/home/administrator/workplace/mochiweb_example/deps/mochiweb/include"]

  我们回到调用这个函数的mochiweb_example_deps:ensure/1 函数:

%% @spec ensure(Module) -> ok
%% @doc Ensure that all ebin and include paths for dependencies
%%      of the application for Module are on the code path.
ensure(Module) ->
    code:add_paths(new_siblings(Module)),
    code:clash(),
    ok.

  首先看下函数:code:add_paths/1,erlang doc 地址:http://www.erlang.org/doc/man/code.html#add_paths-1,如下图:

   这三个函数比较作用差不多,前两个是添加Dirs中的目录到代码路径的尾部,如果这个目录已经存在,则不添加。无论每个Dir是否有效,这个函数总是返回ok。后面一个则是添加Dirs中的目录到代码路径的头部,其他一样。

  知道这个函数的作用,就知道这里其实是添加 ["/home/administrator/workplace/mochiweb_example/deps/mochiweb/ebin","/home/administrator/workplace/mochiweb_example/deps/mochiweb/include"],这两个目录到代码路径的尾部。我们来做个测试:

  首先是调用 code:add_paths/1 函数前:

11> rp(code:get_path()).
[".","/usr/local/lib/erlang/lib/kernel-2.15.1/ebin",
 ......
 "/usr/local/lib/erlang/lib/common_test-1.6.1/ebin",
 "/usr/local/lib/erlang/lib/asn1-1.7/ebin",
 "/usr/local/lib/erlang/lib/appmon-2.1.14.1/ebin"]
ok

  调用之后,我们在代码路径尾部,可以看到新添加的2个目录:

12> code:add_paths(PL).                         
ok
13> rp(code:get_path()).
[".","/usr/local/lib/erlang/lib/kernel-2.15.1/ebin",
 ......"/usr/local/lib/erlang/lib/common_test-1.6.1/ebin",
 "/usr/local/lib/erlang/lib/asn1-1.7/ebin",
 "/usr/local/lib/erlang/lib/appmon-2.1.14.1/ebin",
 "/home/administrator/workplace/mochiweb_example/deps/mochiweb/ebin",
 "/home/administrator/workplace/mochiweb_example/deps/mochiweb/include"]
ok
14> 

  注意:这里我由于篇幅,我省略掉中间相同的部分。

  最后,我们再看下函数:code:clash/1,erlang doc 地址:http://www.erlang.org/doc/man/code.html#clash-0,如下图:

  搜索整个代码空间模块名称相同的名称并写报告到标准输出。

  测试如下:

  

  好了,到目前为止,这个模块我们已经看完了,这一篇就到这里吧,下一篇我们继续回到 mochiweb_example:start/0 函数,如下面代码,来继续跟大家分享mochiweb源码以及示例源码。

%% @spec start() -> ok
%% @doc Start the mochiweb_example server.
start() ->
    mochiweb_example_deps:ensure(),
    ensure_started(crypto),
    ensure_started(mochiweb_example).

  最后,谢谢大家的耐心观看,咱们下回再见,晚安。