首页 > 解决方案 > 使用保护子句自省函数

问题描述

给定一个具有两个具有相同数量但不同保护子句的函数的模块,我如何(理想情况下)查看这些子句是什么,或者至少有两个函数?

defmodule Test do
  def greet(name) when name == "foo" do
    IO.puts("Hello, bar")
  end

  def greet(name), do: IO.puts("Hello, #{name}")
end

Test.__info__(:functions)不起作用,因为它只会返回[greet: 1]

标签: elixirintrospectionguard-clause

解决方案


您可以将模块的代码反编译为“抽象代码”并深入研究以获取此信息。以下是获取模块中每个函数的子句的方法:

module = Test

{:ok, {^module, [abstract_code: {:raw_abstract_v1, abstract_code}]}} = :beam_lib.chunks(module, [:abstract_code])

for {:function, _, name, arity, clauses} <- abstract_code do
  # Uncomment the next line to print the AST of the clauses.
  # IO.inspect(clauses)
  IO.inspect {name, arity, length(clauses)}
end

输出:

{:__info__, 1, 7}
{:greet, 1, 2}

注意:这可能是私有 API,并且可能会在 Erlang/OTP 的未来版本中发生变化。上面的输出是在 Erlang/OTP 20 上的。


推荐阅读