作为开发者的你平时工作时是怎么判断并清理死代码的?也许你猜到了这篇文章要讲什么,是的,我们是有一些清理死代码的好方法推荐给你……

编译 | 弯月  责编 | 张文

出品 | CSDN(ID:CSDNnews)

对于我们团队来说,有两项工作能让我们感受到满满的成就感:清理死代码和自动化!

因此,在认真考虑了各种自动化工具之余,我们还希望能够遍历所有的代码,分析每一个 .erl 和 .hrl 文件,并输出所有可以删除和/或重构代码的候选列表。

本文介绍的这款工具 Hank 可以帮助你确定哪些是死代码。

Hank 与其他现有工具的区别

你可能想问:“为什么我要选择 Hank?这类的工作可以通过 linter 解决!”

答案是:不,Hank 与 linter 不同。

关于代码的 linting,我们使用 Elvis,它会审核我们的 Erlang 代码风格,比如函数命名、嵌套层级、每一行的长度、变量命名约定等等。

这些不属于 Hank 的工作范围。

Xref 是一种交叉引用工具,可用于查找函数、模块、应用程序以及发行版本之间的依赖关系。它会分析函数的定义和函数的调用,并警告我们源代码中已定义、但从未使用过的函数。

这些也不属于 Hank 的工作范围。

那么 Dialyzer 呢?Dialyzer 是一种静态分析工具,可识别软件差异,例如成功类型的错误,以及由于编程错误而变得无效或无法访问的代码,以及不必要的测试等。它的分析基于的是成功类型的概念。

Hank 不依赖于规范,也不评估函数参数/返回中的“语义”。

Hank 的功能

那么,Hank 究竟有哪些功能?Hank 会检测并警告你代码库中可以被删除,或者可以根据规则重构的代码。

它适用于整个项目(与 Elvis 不同,后者只能处理单个文件),源代码(与 Xref 不同,后者只能处理已编译的代码),以及单个项目(与 Dialyzer 不同,后者将分析整个系统,包括 OTP 以及依赖项)。

如何使用 rebar3_hank

 

你只需要将下列代码添加到rebar.config(项目或全局的~/.config/rebar3/rebar.config):

{plugins, [rebar3_hank]}.

然后运行:

rebar3 hank

接下来就是见证奇迹的时刻!

跳过规则

在某些情况下,你可能需要跳过某些规则,比如正在开发的库,你可以在其中定义供其他使用的 hrl 或模块。在这种情况下,你可能需要忽略一些规则(例如single_use_hrl_attributes)。使用 Xref 也会发生类似的情况。

为此,hank 可以忽略模块级别的规则:

% ignoring all the rules for this module
-hank ignore% or ignoring specific rules
-hank [single_use_hrl_attributes]

或者,在 rebar.config 中添加以下配置:

{hank, [{ignore, [{"test/*.erl", unused_ignored_function_params}
]}]}.

规则

以下是我们创建好的规则,你可以直接在 Hank 中使用。

unused_ignored_function_params

随着函数的不断发展,以前的某些参数可能已不再使用了。最简单的解决方案可能就是忽略它们,然后忘掉这个问题。

Hank 会检测出所有函数中被忽略的参数,并告知你可以删除这些参数,并重构函数的调用,这样就可以让代码更加简洁。

例如,在分析这个模块时……

-module(my_module).-export([external_fun/1]).external_fun(X) ->multi_fun(X,rand:uniform(), undefined).%% A multi-clause function with unused 3rd param
multi_fun(undefined, _, _) ->ok;
multi_fun(Arg1, Arg2, _Arg3) when is_binary(Arg1) ->Arg2;
multi_fun(Arg1, _, _) ->Arg1.

Hank 的输出结果为:

$ rebar3 hank
===> Looking for code to kill with fire...
===> The following pieces of code are dead and should beremoved:
src/my_module.erl:9: Param #3 is not used at 'multi_fun/3'

为了避免这种警告,你可以删除未使用的参数。

single_use_hrls

有时,你会将一些代码放入应该在多个模块之间共享的头文件中,但最终你只编写了一个使用该头文件的模块。在这种情况下,最好将头文件的内容直接放入模块内。Hank 有这样的一个规则!

假设有一个文件 header.hrl:

-define(APP_HEADER, "this is a header from an app that willbe used in just one module").
-define(SOME_MACRO(A), A).-module(app_include_lib).-include("header.hrl").-export([my_function/0]).my_function() ->% those are only usedhere!?SOME_MACRO(?APP_HEADER).

Hank 的输出结果为:

$ rebar3 hank
===> Looking for code to kill with fire...
===> The following pieces of code are dead and should beremoved:
header.hrl:0: This header file is only included at:src/app_include_lib.erl

将这个 hrl 文件的内容直接放入使用该文件的模块中,就不会再看到这则警告了。

single_use_hrl_attrs

有时,情况会更微妙。有时,整个文件并非仅在一个模块中使用,可能在许多模块之间共享。但是某些属性并非如此,例如宏或记录,它们在头文件中定义,但仅在单个模块中使用。Hank 有一条规则,建议你将这些属性放在模块内,以减少不必要的共享内容。

对于上述文件,假设 hrl 包含在另一个文件中:

-module(app_include_lib_2).-include("header.hrl").

Hank 的输出结果为:

$ rebar3 hank
===> Looking for code to kill with fire...
===> The following pieces of code are dead and should beremoved:
include/header.hrl:2: ?SOME_MACRO/1 is used only at src/app_include_lib.erl

unused_hrls

有时,情况会更加恶劣,有的 hrl 文件可能没有包含在任何模块中。Hank 会检测到它们,并告知你可以将其完全删除,因为实际上它们没有任何作用。

添加一个未包含在任何模块中的 header_2.hrl 文件,Hank 的输出结果为:

$ rebar3 hank
===> Looking for code to kill with fire...
===> The following pieces of code are dead and should beremoved:
include/header_2.hrl:0: This file is unused

unused_macros

Hank 还有一条规则,它将检测项目中未使用的宏。这些宏可能定义在了源代码中的任何文件中,但是从未使用。因此,这些宏都是没有必要的,可以删除。

unused_record_fields

这个规则很重要。根据这个规则,Hank 会发现某些记录声明带有字段定义(甚至为它们提供默认值),但从未使用过。Hank 认为访问或写入记录字段就是在使用它。

你可以通过这个警告,删除记录中未使用的字段,从而减小记录的大小。

可扩展性

我们非常注重该项目的可扩展性,任何人都可以通过实现 hank_rule 的行为来编写自己的项目规则。

但是,如果你觉得新规则具有广泛适用性的话,可以贡献到 rebar3_hank 的 GitHub 社区!你可以查看未解决的议题,并随时创建新的议题!

测试 Hank 的威力

为了让你了解 Hank 的功能,我们决定在一个很大的代码库中对其进行测试。

我们决定尝试使用 Erlang / OTP。由于这个项目主要由各种库组成,因此我们必须限制应用哪些规则,以免产生一些虚假的结果。我们使用了以下配置:

{hank, [{ignore,["**/test/**"]}, %% Just "production" code, no tests{rules, [unused_ignored_function_params,unused_hrls,unused_macros,unused_record_fields]}
]}.

我们知道会找到大量警告,但是最终的结果还是超出了预期。Hank 找到了 OTP 生产代码中的 4000 多条死代码。

虽说并不是所有收到警告的代码都应该被删除,但是通过这个例子,你也看出了 Hank 的威力。以下是 Hank 输出的警告……

记录中未使用的字段

Hank 找到了 130 多个包含未使用字段的记录,例如 erl_tidy 或 remote_logger。

未使用的宏

Hank 在 OTP 中发现了 1000 多个未使用的宏,其中大多数出现在 megaco 应用程序的大型模块中,还有一些出现在其他宏中,比如 xmerl_uri。

未使用的参数

Hank 还发现了 2000 多个函数带有未使用的参数。其实有些不是真正的错误,但有些值得仔细检查。比如这个例子(https://github.com/erlang/otp/blob/6378a0c825db64df91e01ee39e3a268f4ba050b7/lib/inets/src/http_lib/http_uri.erl#L257-L266),该参数从未使用过第一个参数。(转自CSDN)

参考链接:https://tech.nextroll.com/blog/dev/2021/01/06/erlang-rebar3-hank.html

1.国产替代摸不着门儿?快来回看兆易创新直播课!

2.开源的RISC-V能否成为中国“缺芯”的解药?

3.树莓派Pico:仅4美元的MCU

4.MCU支持AI功能的多种原因~

5.2020年,我学习到的20条软件工程准则~

6.状态机思路在嵌入式开发中的应用~

免责声明:本文系网络转载,版权归原作者所有。如涉及作品版权问题,请与我们联系,我们将根据您提供的版权证明材料确认版权并支付稿酬或者删除内容。

关于清理「死代码」,这些好方法推荐给你!相关推荐

  1. 关于清理「死代码」,我有一些好方法推荐给你

    [CSDN 编者按]作为开发者的你平时工作时是怎么判断并清理死代码的?也许你猜到了这篇文章要讲什么,是的,我们是有一些清理死代码的好方法推荐给你-- 编译 | 弯月  责编 | 张文 出品 | CSD ...

  2. 为什么 LeetCode(力扣)「执行代码」正确,提交代码出错?

    为什么有时在 LeetCode (力扣)上,Run Code(执行代码) 正确,Submit(提交代码)时提示 Wrong Answer(解答错误)? 看这篇文章你就懂了,真不是 LeetCode 出 ...

  3. 前端已死?我看未必,但「低代码」已剑指前端程序员

    本文笔者会从以下几个方面分享,希望能够帮助正在迷茫的前端小伙伴提供一点思路! 逛技术博客 不局限框架 全栈工程师兴起 关注前沿 写技术文章 录制前端视频 总结 2023第一季度快过去了,没工作的找到工 ...

  4. 谁在抢占「低代码」高地?

    [深几度·海外观察系列] 撰稿|吴俊宇 审阅|梁欣婷 「摘要:2020年,新冠疫情大流行引发企业快速数字化诉求.低代码开发顺势成为潮流.这股潮流在2021年进一步被推高.但低代码开发不是新鲜事物.20 ...

  5. “00后”来了!数睿数据迎来新生代「无代码」生力军

    "00后"来啦! 7月,数睿数据迎来了首批应届毕业生,活力新生代来袭. 他们大多来自南京大学.南京航空航天大学.中南财经政法大学.南京邮电大学.华东师范大学.新南威尔士大学等国内外 ...

  6. 机器学习实战第一步:特征选择与特征工程「附代码」

    https://www.toutiao.com/a6641904652575048206/ 2019-01-02 22:41:05 特征工程是机器学习的第一步,涉及清理现有数据集.提高信噪比和降低维数 ...

  7. python朋友圈为什么这么火-用Python发一个高逼格的朋友圈「附代码」

    今天小漠要给大家介绍一个Python库: PIL(Python Image Library) 下面我们用一个实际的例子 看看50行python代码可以做什么神奇的事情 这是小漠发的一个朋友圈 切图前是 ...

  8. CSDN企业数字化之路 ——「低代码」发展研讨会北京站现场实录大放送

    作者 | 千鸟 出品 | CSDN云计算(ID:CSDNcloud) 2021年底,CSDN面向行业开发者和高校学生开发者,展开了关于"低代码"的开发者调研活动.基于调研数据,CS ...

  9. python数据变更邮件提醒_Python之Bilibili自动更新邮件提醒并任务栏图标「完整代码」...

    前言 本次分享的是小编经过多日编写的关于自动检测B站Up主视频更新情况,并发送邮件提醒更新的Python程序,代码不专业.部分代码段借鉴网上,仅供参考娱乐! 用到的库 selenium._thread ...

最新文章

  1. 写代码的16个好习惯,减少80%的bug
  2. java开发 职业技能_java编程开发程序员需要具备哪些职业技能
  3. 按钮button加超链接
  4. 设计灵感|简单的文字和图片排版如何出彩?
  5. Softreference | WeakReference
  6. springmvc框架使用拦截器实现301永久重定向,其实用过滤器应该是更好
  7. 一招解决二级域名下session失效问题
  8. 陆振波的svm的matlab代码的解释,陆振波SVM的MATLAB代码解释
  9. 复制百度文库及其他收费文档的方法
  10. 高级项目管理-3、项目立项、变更、整体管理
  11. 计算机函数求销售额公式,excel用函数求出销售额 使用TREND函数来对销售额进行预测的方法...
  12. 分享:映像编辑工具Ghostexp
  13. java中抽象类继承抽象类_邮政编码作为Java中抽象类的示例
  14. 如何查询SCI检索号?
  15. C#.NET面试题:一批编号为1-100全部开关朝上(开)的灯进行以下操作: 开关编号凡是1的倍数反方向拨一次开关;若该编号也是2的倍数反方向又拨一次开关;若该编号又是3的倍数反方向又拨一次开关……
  16. 目前住院病人需要护士护理,这样做不仅需要大量护士,而且由于不能随时观察病人情况,还可能会延误抢救时即。某医院呢打算开发一个以计算机为中心的患者监护系统,试写出问题定义,并分析开发这个系统的可行性
  17. Springboot配置保存日志文件
  18. 目标检测(后处理):从 NMS 到 Soft-NMS 到 Softer NMS
  19. csharp基础练习题:小数的位数【难度:1级】--景越C#经典编程题库,不同难度C#练习题,适合自学C#的新手进阶训练
  20. 3.3.6 全微分与复合求导

热门文章

  1. 2018兰亭序系列书法作品集
  2. 【Luat】3. 下载lua文件
  3. ArcGIS安装过程中的“需要microsoft.net framework 3.5 sp1或等效环境“问题
  4. 【数据结构入门篇】数据结构与算法同我一起从入门开始,到入土为止
  5. 不黑学社代表孙溟㠭匪石参访南普陀寺
  6. Oracle Level ?*
  7. 小技巧 - 一键屏蔽百度搜索出现百家号信息的方法
  8. 厦门理工计算机课设,厦门理工c++课程设计.doc
  9. Html源代码(特效)
  10. 第002课 ubuntu环境搭建和ubuntu图形界面操作(免费)