鸿 网 互 联 www.68idc.cn

当前位置 : 服务器租用 > 编程语言开发 > erlang > >

mochiweb 源码阅读(三)

来源:互联网 作者:佚名 时间:2012-11-15 13:35
大家好,周末总是过的那么快,周六跟北京几个Erlang开发者去森林公园玩了一天,打打三国杀,下下象棋,聊聊天。能多出去走走,认识认识其他的Erlang开发者,还是挺爽的一件事。晚上闲下来,静下心来跟大家继续分享mochiweb源码。 在上一篇,我们简单了学习了

  大家好,周末总是过的那么快,周六跟北京几个Erlang开发者去森林公园玩了一天,打打三国杀,下下象棋,聊聊天。能多出去走走,认识认识其他的Erlang开发者,还是挺爽的一件事。晚上闲下来,静下心来跟大家继续分享mochiweb源码。

  在上一篇,我们简单了学习了几个Erlang的系统函数,以及函数往下看:

%% @spec new_siblings(Module) -> [Dir] %% @doc Find new siblings paths relative to Module that aren't already on the %% code path. new_siblings(Module) -> Existing = deps_on_path(), SiblingEbin = filelib:wildcard(local_path(["deps", "*", "ebin"], Module)), Siblings = [filename:dirname(X) || X <- SiblingEbin, ordsets:is_element( filename:basename(filename:dirname(X)), Existing) =:= false], lists:filter(fun filelib:is_dir/1, lists:append([[filename:join([X, "ebin"]), filename:join([X, "include"])] || X <- Siblings])).

  这里我们从上一篇知道了函数:

%% @spec local_path([string()], Module) -> string() %% @doc Return an application-relative directory from Module's application. local_path(Components, Module) -> filename:join([get_base_dir(Module) | Components]).

  这里两个参数的值为:

  < Components = ["deps","*","ebin"]
  < Module = mochiweb_example_deps

  这个函数就一行代码,首先调用 mochiweb_example_deps:get_base_dir/2 函数,传递参数 Module

%% @spec get_base_dir(Module) -> string() %% @doc Return the application directory for Module. It assumes Module is in %% a standard OTP layout application in the ebin or src directory. get_base_dir(Module) -> {file, Here} = code:is_loaded(Module), filename:dirname(filename:dirname(Here)).

  从注释来看,大意是:返回模块所在的应用程序目录,它假定模块在一个标准的OTP应用程序的ebin或src目录。

  我们先看下函数 code:is_loaded/1,检查该模块是否加载,香港空间,如果已加载,返回{file, Loader};否则返回false, erlang doc 地址:,如下图:

  这里:< Here = "/home/administrator/workplace/mochiweb_example/ebin/mochiweb_example_deps.beam",而 filename:dirname/1 这个函数前一篇我们已经讲过了:Returns the directory part of Filename

  我们对这个函数稍加修改来看下执行过程具体获得到的值,如下图:

  

  从上面这个图,我们能很明白的看到整个函数执行的每一步,这里主要跟大家提下,filename:dirname/1 这个函数接受的参数不一定是文件路径,也有可能是目录路径,如果是目录路径,则返回的是上一层目录的路径,如D2的值。

  知道了这个函数的作用,我们接着回到函数返回的值和Components组合成一个List,传递给函数:filename:join/1,这个函数的erlang doc 地址:,如下图:

  这个方法也很简单,拼接路径,我们看下:

  filename:join(["/home/administrator/workplace/mochiweb_example" | ["deps","*","ebin"]]).

  = "/home/administrator/workplace/mochiweb_example/deps/*/ebin".

  回到mochiweb_example_deps:new_siblings/1 函数往下看,这里我们看下函数:filelib:wildcard/1,erlang doc 地址:,如下图:

  这个方法也挺简单的,香港服务器,按照一定的规则去模式匹配并返回匹配的文件列表,我做了写测试,如下图:

  

  

  我们看下:

  SiblingEbin = filelib:wildcard(local_path(["deps", "*", "ebin"], Module))

  = filelib:wildcard("/home/administrator/workplace/mochiweb_example/deps/*/ebin")

  = ["/home/administrator/workplace/mochiweb_example/deps/mochiweb/ebin"]

  继续往下看:

Siblings = [filename:dirname(X) || X <- SiblingEbin, ordsets:is_element( filename:basename(filename:dirname(X)), Existing) =:= false],

  我们先看下函数:ordsets:is_element/2,判断Element是否是Ordset的元素,是则返回true, 否则返回flase。erlang doc 地址:,如下图:

  从上来文,我们知道:

  < Existing = []
  < SiblingEbin = ["/home/administrator/workplace/mochiweb_example/deps/mochiweb/ebin"]

  所以得到:

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

  如下图:

  

  好了,这一篇就到这了,下一篇我们从下面代码处继续往下看:

网友评论
<