善待Erlang 代码 -- Xref 实践
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 实践的更多相关文章
- 善待Erlang 代码 -- 巧用 user_default
这是一篇水文 ----------------------------------------------------- 很好用的一个技巧 http://www.erlang.org/doc/man/ ...
- HTML 代码复用实践 (静态页面公共部分提取复用)
原文:HTML 代码复用实践 上面的链接里面安装配置步骤已经非常详细,这里主要记录我操作过程中遇到的几个问题 gulp-file-include 的使用 按上面的步骤安装之后,node_mod ...
- Tsung脚本中使用动态参数(一)---直接在脚本里编写Erlang代码
杀死一个程序猿,只要改三次需求.同理,杀死一个接口自动化测试人员,只要改三次接口数据处理方式.我目前的状态,改了一次接口数据处理方式,有一种胸闷的感觉. 因为改需求,所以,要改脚本.T_T.所以,才有 ...
- elixir 调用erlang 代码
备注: 项目比较简单,主要是elixir 混合erlang 代码,elixir 调用erlang 模块方法 1. 初始化项目 mix new erlangelixirdemo 项目结构如 ...
- 理想的DevOp流程怎么做?看看Slack的代码部署实践 原创 Michael Deng 高可用架构 今天
理想的DevOp流程怎么做?看看Slack的代码部署实践 原创 Michael Deng 高可用架构 今天
- git 操作 :从远程仓库gitLab上拉取指定分支到本地仓库;git如何利用分支进行多人开发 ;多人合作代码提交实践
例如:将gitLab 上的dev分支拉取到本地 git checkout -b dev origin/dev 在本地创建分支dev并切换到该分支 git pull origin dev 就可以把git ...
- 敏捷开发中高质量 Java 代码开发实践
Java 项目开发过程中,由于开发人员的经验.代码风格各不相同,以及缺乏统一的标准和管理流程,往往导致整个项目的代码质量较差,难于维护,需要较大的测试投入 和周期等问题. 这些问题在一个项目组初建.需 ...
- erlang代码片段
转载自http://blog.csdn.net/sw2wolf/article/details/6797708 .列表操作 lists:foreach(fun(X) -> io:format(& ...
- Android ------ 美团的Lint代码检查实践
概述 Lint是Google提供的Android静态代码检查工具,可以扫描并发现代码中潜在的问题,提醒开发人员及早修正,提高代码质量.除了Android原生提供的几百个Lint规则,还可以开发自定义L ...
随机推荐
- 20145325张梓靖 《Java程序设计》第2周学习总结
20145325张梓靖 <Java程序设计>第2周学习总结 教材学习内容总结 整数 short 2字节,int 4字节,long 8字节 字节 byte 1字节 浮点数 float 4字节 ...
- Hadoop运维手记
1.处理hadoop的namenode宕机 处理措施:进入hadoop的bin目录,重启namenode服务 操作命令:cd path/to/hadoop/bin ./hadoop-daemon.sh ...
- 内核加载模块时提示usb_common: exports duplicate symbol of_usb_get_dr_mode
1.分析: 既然符号重复了,那么说明有一个部分既被编译到内核中也被编译成模块了,因此在加载模块时,内核报符号重复的提示 2.解决 直接配置内核的某一部分编译成模块,例如笔者就直接将USB这一部分编译成 ...
- P4factory ReadMe Quickstart 安装p4factory
操作系统: Ubuntu 14.04 前言 在之前,我直接从P4.org给的GitHub网址上下载了p4factory,但是在根据ReadMe的内容进行QuickStart的时候,发生了shell脚本 ...
- Validate Binary Search Tree,判断是否是二叉排序树
算法分析:两种方法,一种是中序遍历,然后得到一个序列,看序列是否是有序的.第二种,是用递归. 中序遍历: public class Solution { List<Integer> lis ...
- hdu 4549 M斐波那契数列 矩阵快速幂+欧拉定理
M斐波那契数列 Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others) Problem ...
- 从零开始,使用Docker Swarm部署集群教程
本文首先从Dockerfile创建了一个简单web镜像 然后将web镜像推送到了远程仓库,以备后面集群中不同机器自动下载 之后使用docker-compose.yml配置了一个应用 而后新建了2台虚拟 ...
- shell 使用ping测试网络
能ping通返回1,不能返回0 ping -c 192.168.1.1 | grep '0 received' | wc -l
- Qt5_vs2013_error_C2001: 常量中有换行符__资料
ZC: Win7x64 + Qt551(x86) + vs2013(x86) ZC: 问题:UTF-8 在源码文件中有中文时,有时会报编译错误:C2001 & C2143 分析: --> ...
- Eclipse.修改项目的JDK版本
1.我实际使用过程中,只是修改了 项目右键-->Properties-->左侧选择"Java Compiler" -->右侧的"JDK Complian ...