Elixir是否有类似Lisp trace宏的函数调用输入输出追踪工具?
在Elixir中实现类似Lisp
trace宏的函数追踪功能 当然有啦!在Elixir里,你可以通过原生工具或者第三方库实现和Common Lisp中trace宏几乎一样的函数追踪效果,能清晰看到函数调用的输入参数、返回值,甚至调用栈的层级关系。
1. 用Elixir自带的:dbg模块(原生方案)
Elixir基于Erlang VM,所以可以直接使用Erlang的:dbg模块来追踪函数调用,不需要额外安装依赖。
先定义你的阶乘函数:
defmodule Math do def fact(0), do: 1 def fact(n), do: n * fact(n - 1) end
然后在IEx中启动调试并设置追踪规则:
# 启动dbg服务 :dbg.start() # 追踪Math模块下的fact函数,匹配任意参数 :dbg.trace(:call, {Math, :fact, :_}, []) # 开启返回值追踪,这样能看到函数退出时的返回结果 :dbg.trace(:return_from, {Math, :fact, :_}, [])
现在调用Math.fact(3),你会看到类似这样的输出(格式遵循Erlang调试工具的风格,但核心信息完整):
(<0.123.0>) call Math.fact(3) (<0.123.0>) call Math.fact(2) (<0.123.0>) call Math.fact(1) (<0.123.0>) call Math.fact(0) (<0.123.0>) returned from Math.fact/1 -> 1 (<0.123.0>) returned from Math.fact/1 -> 1 (<0.123.0>) returned from Math.fact/1 -> 2 (<0.123.0>) returned from Math.fact/1 -> 6
2. 用第三方库获得更贴近Lisp风格的层级输出
如果你想要和你给出的Common Lisp示例一样的缩进式层级输出,可以使用第三方库mix_trace,它专门针对Mix环境做了友好的格式化。
首先在mix.exs中添加依赖:
defp deps do [ {:mix_trace, "~> 0.2", only: :dev} ] end
安装依赖后,在终端运行:
mix trace Math.fact/1
接着在IEx中调用Math.fact(3),就能看到和Lisp trace几乎一致的输出:
==> Entering Math.fact(3) ==> Entering Math.fact(2) ==> Entering Math.fact(1) ==> Entering Math.fact(0) <== Exiting Math.fact/1 with return value: 1 <== Exiting Math.fact/1 with return value: 1 <== Exiting Math.fact/1 with return value: 2 <== Exiting Math.fact/1 with return value: 6 6
这种格式能直观展示函数调用的嵌套层级,和你提供的Common Lisp示例体验完全匹配。
内容的提问来源于stack exchange,提问作者mszmurlo
相关产品推荐
相关产品推荐

