`
cryolite
  • 浏览: 579684 次
  • 性别: Icon_minigender_1
  • 来自: 北京
社区版块
存档分类
最新评论

dialyzer: Erlang代码分析器

阅读更多
dialyzer: Erlang代码分析器

Erlang是一种“动态”语言,这会带来一个问题,单元测试不足以证明我写的代码是否足够正确。很难发现动态语言类型错用的问题。静态类型语言倒是很容易找到此类错误,但是Erlang是“动态的”。

例如,length/1函数只能处理类型为列表(list)的参数,如果传入的不是列表,比如传入一个atom就会出错,但是程序中这样的代码是能够通过编译的,运气好的话会有一个警告,运气差的话只能在运行时发现出错。例如以下代码能成功的编译,也不会有警告,但是显然代码是有问题的,这个问题只能在运行时(foo函数被调用时)才能发现:
bar(List) ->
    abc.

foo() ->
    V1 = bar([]),
    io:format("length: ~p~n", [length(V1)]).  %% 这里V1必须是list才行,但是编译时是没法知道的,只有运行时才会发现这个错误


同样的例子,exit/2函数的第一个参数必须是Pid,如果不是也能顺利通过编译,这样只能在运行时才会被发现

此外,我自己写的函数,比如bar函数,可能业务逻辑决定了传入的参数必须是list,返回的参数也应该是list,如果不是,那调用者肯定错误的使用了此函数。在动态语言中很难做到对参数类型和返回类型的限制。

也就是说,对库的接口的错误理解和错误使用是Erlang这样的动态语言常见问题。为此设计了一套合约语言(contract language),有了合约(contract),dialyzer能够很容易的检测到误用的接口

有两种建立合约的方式,一种是在注释里使用@spec这样的annotation,另一种是spec声明
例如规定bar函数只能接收atom或整数,只能返回atom的list:
-type bar_thing() :: atom() | integer().  %% 类型声明:定义bar函数能接收的参数类型
-type ret_thing() :: [atom()].  %% 类型声明:定义bar函数的返回类型

-spec bar(bar_thing()) -> ret_thing(). %% 函数合约:bar函数的参数和返回值

或者
-spec bar(Arg::atom()|integer()) -> [atom()].

另一种是使用annotation的方式,(注意注释中spec要以点号结束annotation,不然无效):
%% @spec bar(Arg::atom()|integer()) -> [atom()].


正如注释一样,annotation不会影响编译。

不过,违反了合约(contact)依然能顺利编译通过,但是我们现在就可以通过dialyzer工具分析源代码找出所有违反合约的代码
dialyzer --src -c test1.erl

可以一次分析工程中的所有文件
dialyzer --src -I ./include -c *.erl
但是可能会有太多的警告信息了,也可以一个文件一个文件的分析,处理起来容易一点

注1:使用dialyzer工具前需要先构建plt:
dialyzer --build_plt -r $OTP_HOME/lib/kernel-2.12.4/ebin\
$OTP_HOME/lib/stdlib-1.15.4/ebin\
$OTP_HOME/lib/mnesia-4.4.5/ebin (或者其它更多的模块)
这一过程耗时很长(大概5分多钟),成功后会在我的home目录下创建一个叫.dialyzer_plt的文件
注2:有个万能类型any()可以代表任意的数据类型;
注3:可以将多个文件中用到的类型(比如pos())集中到一个erl文件中(比如m.erl),通过m:pos()使用该类型;或者将该类型集中到头文件hrl中,使用时包含进来。
注4:typer工具可以列出所有声明的合约

总结:
可以通过确定某种编程规范以及使用Dialyzer这样的工具分析代码是否正确,克服动态语言的弱点。声明和合约一般不影响编译和运行。所以编译通过不一定代表合约有效,还需要dialyzer工具分析

更详细的介绍见
Gradual Typing of Erlang Programs: A Wrangler Experience
分享到:
评论

相关推荐

    erlang_examples:演示ERLANG所有功能的源代码集合

    本资源“erlang_examples”提供了一个丰富的源代码集合,旨在全面展示Erlang的各种功能和特性。下面我们将深入探讨Erlang的关键概念及其在实际应用中的体现。 1. **函数式编程**: Erlang是纯函数式编程语言,这意味...

    Erlang程序设计

    8. **类型系统**:尽管Erlang是动态类型的,但随着Erlang/OTP的版本更新,类型注解和静态类型检查工具如 Dialyzer 的引入,为代码的静态分析提供了可能,提高了代码质量。 9. **热升级**:Erlang系统支持在线代码...

    rebar3_hank:Erlang死代码清除器

    rebar3_hankErlang死代码清除器 Scorpio先生说生产率提高了2%,这全是因为我的动机技巧,例如甜甜圈和更多甜甜圈的出现。 (荷马·辛普森一家)建造$ rebar3 compile测试$ rebar3 test使用将插件添加到您的钢筋配置...

    erlang otp 19.1 官网文档 HTML格式

    - **Dialyzer**:静态代码分析工具,用于找出潜在的错误和类型不匹配。 - **公共API工具**:如XML和JSON解析器,日期和时间处理,以及其他通用功能。 **5. PR.template** `PR.template`可能是Pull Request模板,...

    awesome-erlang:精选的Erlang库,资源和闪亮内容的精选列表

    - ** Debugger**:Erlang的内置调试器,帮助定位和修复代码问题。 - ** Dialyzer**:静态分析工具,可以检测出程序中的类型错误和潜在问题。 通过这个"awesome-erlang"列表,你可以逐步探索Erlang的世界,从基础...

    erlang-rand-compat:Erlang随机数兼容性库

    Erlang随机数兼容性库 ... 避免运行时生成的模块还具有不向Dialyzer隐藏代码的好处。 使用 首先,我们需要生成并加载模块: {ok, rnd} = rand_compat:init(). 或者,您可以指定生成的模块的名称,如下所示: {ok, s

    vscode:用于Erlang语言服务器的Visual Studio代码扩展

    使Dialyzer开心起来从未如此简单。 猫王诊断 在线显示风格的建议。 不再有同事挑剔的评论! 埃多克 将鼠标悬停在本地或远程功能上以查看其edoc 。 当edocs不可用时,您会非常想念此功能,您将开始编写它们! 导航

    E语言搜索代码

    10. **代码分析工具**:除了编写自己的搜索工具,也可以利用现有的Erlang代码分析工具,如 Dialyzer,它能静态分析代码,找出潜在的问题和错误。 了解以上知识点,并结合实际项目需求,开发者可以创建出高效且功能...

    erlang的小型游戏服务器

    `dialyzer_emakefile`和`Emakefile`是Erlang的Dialyzer工具配置文件,Dialyzer是一个静态分析工具,用于检查代码中的错误和潜在问题,提高代码质量。`version.txt`则记录了项目的版本信息,这对于追踪代码的迭代和...

    eplugin:一个Erlang插件管理器

    该库旨在提供一种简单的方法来管理Erlang应用程序的插件,目前抽象非常简单并且层次很高,但是非常灵活。 用法 只需启动应用程序,此刻只有一个名为plugin_dir配置变量,顾名思义,该变量指定了在何处发现插件。 它...

    erlex:将Erlang样式结构和错误消息转换为等效的Elixir

    Dialyzer是Erlang的一个静态类型分析工具,它可以检查代码中的潜在错误和类型不匹配问题。Dialyxir是Elixir的包装器,使得Elixir项目可以利用Dialyzer的强大功能,但与Elixir的构建流程更好地集成。 在Elixir项目中...

    SublimErl:用于Sublime Text 2的Erlang插件,可以完成代码并允许您在编辑器中运行测试

    允许您自动缩进您的Erlang代码 运行Eunit测试(模块的所有测试/单个测试) 运行通用测试(该模块的所有测试) 运行Dialyzer测试(单个模块) 轻松转到项目的任何导出功能 从文本编辑器访问手册页 全部在您的测试...

    杭州ecug会议上的演讲稿

    这个PPT文件很可能是演讲的幻灯片,详细讲解了如何优化Erlang代码,可能包含以下内容: 1. **Erlang语言特性**:介绍Erlang的并发模型(轻量级进程)、消息传递、错误处理和热代码替换等核心概念。 2. **源码分析**...

    erlang:二郎课程

    Erlang交互式shell(通常称为REPL)是学习和调试Erlang代码的有效工具。它允许开发者即时运行代码、测试表达式和查看数据结构。 ### 9. BEAM虚拟机 Erlang运行在BEAM虚拟机上,这个虚拟机专为并发和实时性优化,...

    erlang环境配置借鉴.pdf

    % Dialyzer enhanced flymake checker for Erlang % Copyright (c) 2011, bkil.hu % This program is free software and can be distributed under the terms of % the GNU General Public License v2, % see ...

    Dialyxir:混合任务以简化Elixir项目中Dialyzer的使用

    这使得开发者能够在不离开熟悉的Mix环境的情况下,方便地进行代码分析。 3. **错误报告**:Dialyxir对Dialyzer的输出进行了格式优化,使其更易于理解和解决。它会将复杂的错误信息转化为更易读的形式,帮助开发者...

    erlang环境配置[定义].pdf

    最后,为了进行语法检查和错误提示,用户添加了Flymake插件,特别是针对Erlang的Dialyzer增强版检查器`check_error.erl`。Flymake可以实时检测代码中的错误,提高代码质量。 通过以上步骤,用户成功地在Windows环境...

    《Erlang程序设计》源码

    虽然Erlang本身是一种动态类型语言,但随着Erts(Erlang Run-Time System)的更新,它引入了类型注解和静态类型检查工具如 Dialyzer,帮助开发者发现潜在的问题和提高代码质量。 9. **并发编程实践** 书中通过...

    otp_win64 window10安装包

    3. 工具集:如REPL(Read-Eval-Print Loop)用于交互式编程, Dialyzer进行静态代码分析,以及 Debugger 和 Profiler 用于调试和性能优化。 4. 分布式能力:OTP提供了内置的分布式通信协议和工具,使得Erlang节点...

    Dialyzex:一个Mix任务,用于使用Dialyzer对Elixir项目进行类型检查

    在Elixir编程语言中,Dialyzer是一个强大的静态分析工具,它能够分析代码的PLT(进程字典表,Process Dictionary Table)以检测潜在的错误、类型不匹配和未定义的行为。`Dialyzex`是专门为Elixir构建的一个Mix任务,...

Global site tag (gtag.js) - Google Analytics