Elixir 从零 · 第 30 课(展开目录)
01 · 先让代码说话02 · 先认六种值03 · 把值装起来04 · 从旧 list 生成新 list05 · 让形状对上06 · 用 case 做选择07 · 把文字安全变成整数08 · 拆开 &1 和管道09 · 把代码放进项目10 · 真假不只靠 true11 · 走进嵌套数据12 · 一字不一定一字节13 · 让函数按形状接活14 · 把一列数收成一个值15 · 给不同问题选不同路16 · 给 map 一张名片17 · 让项目自己验答案18 · 让成功和失败长得一样19 · 读写文件先管好路20 · 只算眼前需要的21 · 同一句话,不同做法22 · 先约好模块会做什么23 · 把数据形状写在门口24 · 测试不只看一条好路25 · 把项目磨成一个命令26 · 定下小项目边界27 · 把真实文字洗干净28 · 只开三扇门29 · 把约定钉在代码旁30 · 打包,也留下脚印31 · 照任务书交卷
ELIXIR · 作品 · LESSON 3050 分钟
打包,也留下脚印
把命令构建成 escript,用 Logger 记录失败原因与耗时。
01 · 先看完整例子
让 CLI 只负责边界
print/1 与 fail/1 留在 CLI 边界;mix.exs 配置 main_module: TrailStats.CLI。
Elixir
defmodule TrailStats.CLI do
require Logger
def main(args) do
case run(args) do
:ok -> :ok
{:error, _reason} -> System.halt(1)
end
end
# 测试调用 run/1;只有打包入口 main/1 决定退出状态
def run([path]) do
{micros, result} = :timer.tc(fn -> TrailStats.Parser.read(path) end)
Logger.info("read path=#{inspect(path)} duration_us=#{micros}")
# CLI 把内部数据翻译成终端文字
case result do
{:ok, lines} -> print(TrailStats.count(lines))
{:error, reason} -> fail(reason)
end
end
def run(_args), do: fail(:usage)
defp print(stats) do
IO.puts("lines=#{stats.lines}")
IO.puts("words=#{stats.words}")
IO.puts("chars=#{stats.chars}")
:ok
end
defp fail(reason) do
Logger.error("read_failed reason=#{inspect(reason)}")
IO.puts(:stderr, "无法读取输入文件")
{:error, reason}
end
end先对照结果
- 成功打印
lines=...、words=...、chars=...;打包命令失败时写入标准错误并以状态 1 退出。
02 · 回头拆代码
从第一行往下读
- 计时包住文件读取,结果和耗时一起返回。
- CLI 调用 Parser 与统计 API,不复制两者逻辑。
- 日志只放定位所需信息,避开文件正文。
03 · 认清新符号
符号不是暗号
Logger.info/error写不同级别的结构化运行线索。
System.halt/1只在 CLI 最外层用指定状态结束 BEAM。
:timer.tc/1测量函数运行微秒数并返回结果。
04 · 代码里的概念
把名字和意思对上
可观察性
通过日志、指标等外部信号理解程序运行了什么、在哪里失败。
退出状态
命令交给操作系统的结果数字;0 通常表示成功,非 0 表示失败。
05 · 再说清楚
这些写法为什么有用
命令行输出给使用者看,日志给维护者查问题。两者不要混成一锅。
成功时打印稳定三行;失败时向标准错误写一句短话,并由最外层返回非零退出状态。
Logger 记录路径、失败类别和耗时,不记录完整文件内容。可观察不等于把用户数据全抄进日志。
06 · 自己改一次
合上答案,动手
补全构建前的三条检查命令。
练习起点
mix format ____
mix ____
mix escript.____目标结果: 依次运行格式检查、测试、escript 构建。
卡住了,再看提示
填写 --check-formatted、test、build。
运行过以后,再看一种答案
一种答案
# 先检查,再构建
mix format --check-formatted
mix test
mix escript.build想一想:为什么日志里不记录读取到的完整文件内容?
正文可能很大或含隐私;路径、原因和耗时通常已足够定位问题。
带走
记住三句
- 1
CLI 只处理输入输出边界。
- 2
日志记录必要线索,不泄露正文。
- 3
格式、测试通过后再构建。
本课结束代码也跑过一次,就把这一课收好。