Erlang Thursday – erl_tidy:file/1

今天的Erlang Thursday我们看看Erlang的 erl_tidy 模块,我们从 erl_tidy:file/1 开始。

erl_tidy:file/1 入参是一个文件名,它整理并简洁美观地输出入参指定的文件的源码。

在我的tmp目录里有我解决 FizzBuzz 的快速实现模块,我将看看 erl_tidy:file/1 如何处理这个文件,因为我确定它的处理不是那么的漂亮。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-module(fizzbuzz).
-export([fizzbuzz/1]).
fizzbuzz(N) ->
Translations = lists:map(fun translate/1, lists:seq(1, N)),
lists:foreach(fun(Item) -> io:format("~s~n", [Item]) end, Translations).
translate(N) when N rem 3 =:= 0 andalso N rem 5 =:= 0 ->
'FizzBuzz';
translate(N) when N rem 3 =:= 0 ->
'Fizz';
translate(N) when N rem 5 =:= 0 ->
'Buzz';
translate(N) ->
integer_to_list(N).

我们打开一个新的Erlang shell,然后用入参 fizzbuzz.erl 来调用 erl_tidy:file/1 。

1
2
3
4
erl_tidy:file("fizzbuzz.erl").
% fizzbuzz.erl:6: replacing call to `lists:map/2' with a list comprehension.
% fizzbuzz.erl:6: changing application of implicit fun to direct local call.
% ok

看起来它不喜欢我在代码中用map而且它修改了我调用 translate/1 函数的方式。

关掉shell,我们来看看目录下多了什么。

1
2
3
4
ls -l
total 16
-rw-r--r-- 1 proctor staff 402 Sep 9 22:06 fizzbuzz.erl
-rw-r--r-- 1 proctor staff 405 Sep 9 22:05 fizzbuzz.erl.bak

让我们来看看 fizzbuzz.erl.bak ,主要是确认它的内容是 fizzbuzz.erl 的原始内容。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
-module(fizzbuzz).
-export([fizzbuzz/1]).
fizzbuzz(N) ->
Translations = lists:map(fun translate/1, lists:seq(1, N)),
lists:foreach(fun(Item) -> io:format("~s~n", [Item]) end, Translations).
translate(N) when N rem 3 =:= 0 andalso N rem 5 =:= 0 ->
'FizzBuzz';
translate(N) when N rem 3 =:= 0 ->
'Fizz';
translate(N) when N rem 5 =:= 0 ->
'Buzz';
translate(N) ->
integer_to_list(N).

它的确是 fizzbuzz.erl 的原始内容。

现在我们来看看被 erl_tidy:file/1 修改后的 fizzbuzz.erl 文件。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
-module(fizzbuzz).
-export([fizzbuzz/1]).
fizzbuzz(N) ->
Translations = [translate(V1) || V1 <- lists:seq(1, N)],
lists:foreach(fun (Item) -> io:format("~s~n", [Item])
end,
Translations).
translate(N) when N rem 3 =:= 0 andalso N rem 5 =:= 0 ->
'FizzBuzz';
translate(N) when N rem 3 =:= 0 -> 'Fizz';
translate(N) when N rem 5 =:= 0 -> 'Buzz';
translate(N) -> integer_to_list(N).

正如函数输出的两行消息所说的,我们现在用一个列表解析替代map,并且直接调用 translate/1 函数。

它还把传给 lists:foreach/2 的匿名函数的 end 放在新的一行,也把列表 Translations 放在新的一行。

最后,translate/1 三个分支被改成一行,而且文件最后的换行符也被删掉。

据官方文档所讲,如果 fizzbuzz.erl 有任何没使用的函数都会被删除,同时过时的结构和函数也会被修改。

总的来说,这个好用的Erlang应用小工具可以帮助你的代码保持稳定的风格并将代码保持整洁。

原文链接: https://www.proctor-it.com/erlang-thursday-erl_tidy-file-1/