Xref 是一个交叉引用工具,通过分析定义的函数间的调用关系,用于查找函数、 模块、 应用程序和版本之间的依赖关系。

通俗而言,Xref 可以检查代码中函数的调用关系。比如在 moduleA 中的 funA 调用了moduleB 中的funB, 但是moduleB 中并未定义funB,此错误在代码编译期间不能被发现,但是可以通过Xref 检查。

栗子

使用reabr 创建一个application ,命名为xref_test,目录结构如下:

 $ tree
.
├── ebin
│ ├── test.beam
│ ├── xref_test.app
│ ├── xref_test_app.beam
│ └── xref_test_sup.beam
├── rebar
├── src
│ ├── test.erl
│ ├── xref_test.app.src
│ ├── xref_test_app.erl
│ └── xref_test_sup.erl
└── xref.config directories, files

其中 test.erl 的代码为:

 $ cat ./src/test.erl
-module(test).
-export([start/]).
start() ->
test_2:start().

在test module 中定义start/0  函数,其中调用了test_2:start/0 函数,但是此函数并没有定义。这种情况,必然会引发错误,但是在编译期间,并不能发现。

 $ ./rebar com
==> xref_test (compile)
Compiled src/xref_test_app.erl
Compiled src/test.erl
Compiled src/xref_test_sup.erl

OK,上述执行是顺利完成的。但是在运行时,必然会发生错误。

 > test:start().
** exception error: undefined function test_2:start/

那么,怎样才能在运行之前发现这个错误呢?Xref 就应该隆重登场了。

rebar xref

在rebar 中,集成了xref 工具,相关的配置信息如下:

 {xref_warnings, false}.
%% optional extra paths to include in xref:set_library_path/.
%% specified relative location of rebar.config.
%% e.g. {xref_extra_paths,["../gtknode/src"]}
{xref_extra_paths,[]}.
%% xref checks to run
{xref_checks, [undefined_function_calls, undefined_functions,
locals_not_used, exports_not_used,
deprecated_function_calls, deprecated_functions]}.
%% Optional custom xref queries (xref manual has details) specified as
%% {xref_queries, [{query_string(), expected_query_result()},...]}
%% The following for example removes all references to mod:*foo/
%% functions from undefined external function calls as those are in a
%% generated module
{xref_queries,
[{"(XC - UC) || (XU - X - B"
" - (\"mod\":\".*foo\"/\"4\"))",[]}]}.

在rebar.config 文件中,配置好这些信息,执行:

 $ ./rebar xref
==> xref_test (xref)
Warning: test_2:start/ is undefined function (Xref)
src/test.erl:: Warning: test:start/ calls undefined function test_2:start/ (Xref)
ERROR: xref failed while processing /Users/redink/erlang/test/xref_test: rebar_abort

这个时候,错误就能够清晰的看出来了。

xref_runner

xref_runner 是独立于rebar xref 的一个工具,支持在非rebar 组织的项目中使用xref ,友好度很高。

https://github.com/inaka/xref_runner

在rebar node 组织的Erlang release 中,可以使用xref_runner 方便的对apps 目录下的application 进行xref 检查。

xrefr.config 定义:

 $ cat xrefr.config
[
{xref, [
{config, #{dirs => ["./apps/appname/ebin"],
extra_paths => [
"./deps/***/ebin"]}},
{checks, [
undefined_functions
, undefined_function_calls
, locals_not_used
%%, exports_not_used
, deprecated_function_calls
, deprecated_functions
]},
{xref_default, {verbose}}
]
}
].

总结

Xref 非常有用,能帮我们在运行之前尽快的发现代码的错误以及潜在的错误。

扩展阅读:

http://www.erlang.org/doc/apps/tools/xref_chapter.html

善待Erlang 代码 -- Xref 实践的更多相关文章

  1. 善待Erlang 代码 -- 巧用 user_default

    这是一篇水文 ----------------------------------------------------- 很好用的一个技巧 http://www.erlang.org/doc/man/ ...

  2. HTML 代码复用实践 (静态页面公共部分提取复用)

    原文:HTML 代码复用实践 上面的链接里面安装配置步骤已经非常详细,这里主要记录我操作过程中遇到的几个问题 gulp-file-include 的使用     按上面的步骤安装之后,node_mod ...

  3. Tsung脚本中使用动态参数(一)---直接在脚本里编写Erlang代码

    杀死一个程序猿,只要改三次需求.同理,杀死一个接口自动化测试人员,只要改三次接口数据处理方式.我目前的状态,改了一次接口数据处理方式,有一种胸闷的感觉. 因为改需求,所以,要改脚本.T_T.所以,才有 ...

  4. elixir 调用erlang 代码

    备注:    项目比较简单,主要是elixir 混合erlang 代码,elixir 调用erlang 模块方法   1. 初始化项目   mix new erlangelixirdemo 项目结构如 ...

  5. 理想的DevOp流程怎么做?看看Slack的代码部署实践 原创 Michael Deng 高可用架构 今天

    理想的DevOp流程怎么做?看看Slack的代码部署实践 原创 Michael Deng  高可用架构  今天

  6. git 操作 :从远程仓库gitLab上拉取指定分支到本地仓库;git如何利用分支进行多人开发 ;多人合作代码提交实践

    例如:将gitLab 上的dev分支拉取到本地 git checkout -b dev origin/dev 在本地创建分支dev并切换到该分支 git pull origin dev 就可以把git ...

  7. 敏捷开发中高质量 Java 代码开发实践

    Java 项目开发过程中,由于开发人员的经验.代码风格各不相同,以及缺乏统一的标准和管理流程,往往导致整个项目的代码质量较差,难于维护,需要较大的测试投入 和周期等问题. 这些问题在一个项目组初建.需 ...

  8. erlang代码片段

    转载自http://blog.csdn.net/sw2wolf/article/details/6797708 .列表操作 lists:foreach(fun(X) -> io:format(& ...

  9. Android ------ 美团的Lint代码检查实践

    概述 Lint是Google提供的Android静态代码检查工具,可以扫描并发现代码中潜在的问题,提醒开发人员及早修正,提高代码质量.除了Android原生提供的几百个Lint规则,还可以开发自定义L ...

随机推荐

  1. HDU 3339 In Action(最短路+背包)题解

    思路:最短路求出到每个点的最小代价,然后01背包,求出某一代价所能拿到的最大价值,然后搜索最后结果. 代码: #include<cstdio> #include<set> #i ...

  2. Nginx负载均衡之健康检查

    负载均衡实例 http{ upstream myserver { server 10.10.10.1 weight=3 max_fails=3 fail_timeout=20s; server 10. ...

  3. Codeforces Round #404 (Div. 2) A,B,C,D,E 暴力,暴力,二分,范德蒙恒等式,树状数组+分块

    题目链接:http://codeforces.com/contest/785 A. Anton and Polyhedrons time limit per test 2 seconds memory ...

  4. ResourceNotFound: rgbd_launch

    Checking log directory for disk usage. This may take awhile. Press Ctrl-C to interrupt Done checking ...

  5. Java回顾之集合

    在这篇文章里,我们关注Java中的集合(Collection).集合是编程语言中基础的一部分,Java自JDK早期,就引入了Java Collection Framework.设计JCF的那个人,后来 ...

  6. Angel 实现FFM 一、对于Angel 和分布式机器学习的简单了解

    Angel是腾讯开源的一个分布式机器学习框架.是一个PS模式的分布式机器学习框架. https://github.com/Angel-ML/angel   这是github地址. 我了解的分布式机器学 ...

  7. PHP------数组和对象相互转化,stdClass Object转array

    数组转JSON PHP json_encode() 用于对变量进行 JSON 编码,该函数如果执行成功返回 JSON 数据,否则返回 FALSE . JSON转数组 PHP json_decode() ...

  8. 垃圾收集器G1推荐配置

    -XX:OnOutOfMemoryError=kill -9 %p -XX:OnError=jstack -F %p >ErrorDump.log -Xms4g -Xmx8g -server - ...

  9. 平衡二叉树,AVL树之代码篇

    看完了第一篇博客,相信大家对于平衡二叉树的插入调整以及删除调整已经有了一定的了解,下面,我们开始介绍代码部分. 首先,再次提一下使用的结构定义 typedef char KeyType; //关键字 ...

  10. 分析hello.java文件

    使用JavaServer Faces技术的Web模块示例 1.hello1: hello1应用程序是一个web模块,它使用JavaServer Faces技术来显示问候和响应.可以使用文本编辑器查看应 ...