博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
mochiweb 源码阅读(三)
阅读量:5212 次
发布时间:2019-06-14

本文共 3812 字,大约阅读时间需要 12 分钟。

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

  在上一篇,我们简单了学习了几个Erlang的系统函数,以及mochiweb_example_deps:deps_on_path/0 函数,这一篇我们继续从mochiweb_example_deps:new_siblings/1 函数往下看:

%% @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])).

  这里我们从上一篇知道了mochiweb_example_deps:deps_on_path/0 函数返回的值为:Existing = []。我们继续往下看,先看下mochiweb_example_deps:local_path/2 函数:

%% @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的值。

  知道了这个函数的作用,我们接着回到mochiweb_example_deps:local_path/2 函数,这里把mochiweb_example_deps:get_base_dir/2 函数返回的值和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"]

  如下图:

  

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

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

  最后,谢谢大家的耐心阅读,咱们下一篇再见。

  

转载于:https://www.cnblogs.com/yourihua/archive/2012/07/16/2592693.html

你可能感兴趣的文章
python操作mysql数据库
查看>>
codeforces1097D Makoto and a Blackboard 数学+期望dp
查看>>
NOIP练习赛题目4
查看>>
工作996生病ICU,程序员的工作就不能没有加班?
查看>>
Android Eclipse JNI 调用 .so文件加载【转】
查看>>
iOS基于B站的IJKPlayer框架的流媒体探究
查看>>
ios之库Protobuf的使用
查看>>
Hibernate初探之单表映射——第二章:Hibernate进阶
查看>>
QuickHit游戏
查看>>
C#之四十 Winform MD5加密
查看>>
ASP.NET(C#)——GridView刷新
查看>>
ansible案例-安装nginx
查看>>
测试与优化
查看>>
IE9以下浏览器提示升级
查看>>
CSS 3 选择器
查看>>
又是1年过去了。。。
查看>>
我的网站PR升了没有?
查看>>
普通软件项目开发过程规范(一)—— 项目阶段 (转)
查看>>
mongodb 基础知识
查看>>
AngularJs学习笔记(一)----------关于数据绑定
查看>>