Erlang 从零 · 第 30 课(展开目录)
01 · 先打开 erl02 · 先认常见 term03 · 分清两种文字04 · 变量只接一次05 · 拆开一列,再筛一次06 · 把文字安全变成整数07 · 用 case 选一条路08 · 让函数继续走09 · 把代码放进模块10 · 条件必须说真话11 · 一层一层取数据12 · 文字先说清编码13 · 让函数子句排好队14 · 带着累加器往前走15 · 先看值,再选路16 · 给模块立规矩17 · 让 rebar3 管项目18 · 让结果有固定形状19 · 把磁盘当成会失败的邻居20 · 把函数交给 list21 · record 留在院里22 · 先写模块之间的约定23 · 把 term 形状写出来24 · 小测试与整段路25 · 把应用磨成命令26 · 先把小项目圈住27 · 把真实文件洗干净28 · 公开入口越少越稳29 · 把约定留在源码旁30 · 打包,也留下线索31 · 按最初任务交卷
ERLANG · 作品 · LESSON 3050 分钟

打包,也留下线索

构建 escript,用 Logger 记录失败类别和读取耗时。

01 · 先看完整例子

保存为 trail_cli.erl

print/1 只负责显示;在 rebar.config 中配置 escript 主应用。

Erlang
-module(trail_cli).
-export([main/1]).

main([Path]) ->
  {Micros, Result} = timer:tc(fun() -> trail_parser:read(Path) end),
  logger:info("read path=~tp duration_us=~B", [Path, Micros]),

  %% CLI 把内部 term 翻译为终端输出
  case Result of
    {ok, Lines} ->
      print(trail_stats:count(Lines));
    {error, Reason} ->
      logger:error("read_failed reason=~tp", [Reason]),
      io:format(standard_error, "cannot read input~n", []),
      halt(1)
  end.

print(#{lines := Lines, words := Words, chars := Chars}) ->
  %% 三项结果保持固定顺序,方便人和脚本阅读
  io:format("lines=~B~nwords=~B~nchars=~B~n", [Lines, Words, Chars]),
  ok.
先对照结果
  • 成功打印 lines、words、chars。
  • 失败打印短消息、记录 reason,并以状态 1 退出。
02 · 回头拆代码

从第一行往下读

  1. 计时函数同时返回微秒数和 Parser 结果。
  2. CLI 调用已有模块,不复制读取或统计逻辑。
  3. 日志避开文件正文,减少隐私与体积风险。
03 · 认清新符号

符号不是暗号

logger:info/error

记录不同级别的运行线索。

timer:tc/1

返回函数耗时与结果。

halt/1

从 CLI 最外层以指定状态结束运行时。

04 · 代码里的概念

把名字和意思对上

01

可观察性

通过日志等外部信号理解程序运行与失败。

02

退出状态

0 通常表示成功,非 0 表示命令失败。

05 · 再说清楚

这些写法为什么有用

命令输出给使用者看,日志给维护者查问题。成功结果、错误提示和诊断线索要各守位置。

Logger 记录路径、失败类别和耗时,不记录完整文件内容。

只有 CLI 最外层决定退出状态。Parser 和统计模块继续返回普通 term。

06 · 自己改一次

合上答案,动手

补全交付前的检查与构建命令。

练习起点
rebar3 ____
rebar3 dialyzer
rebar3 ____

目标结果: 先运行 EUnit,再运行 Dialyzer,最后 escriptize。

卡住了,再看提示

两个空分别是 eunit 与 escriptize。

运行过以后,再看一种答案
一种答案
%% 在系统终端运行
rebar3 eunit
rebar3 dialyzer
rebar3 escriptize
想一想:为什么不把完整输入文件写进日志?

文件可能很大或含隐私;路径、原因与耗时通常足够定位问题。

带走

记住三句

  1. 1

    CLI 决定显示与退出状态。

  2. 2

    日志只记录必要线索。

  3. 3

    测试、分析通过后再打包。

本课结束代码也跑过一次,就把这一课收好。