检查Elixir模块是否导出特定函数

时间:2016-10-12 20:37:27

标签: elixir

如何检查Elixir模块是否公开了特定的公共方法?如何检查函数是否已使用特定arity公开?

不起作用:

  • Map.methods
  • Map.functions
  • Map.has_function(:keys)

3 个答案:

答案 0 :(得分:11)

the answer hereforum discussion here的基础上,有几种方法可以做到:

检查模块

是否存在功能

您可以检查函数名称是否作为Map.__info__(:functions)

中的键存在
module = Map
func   = :keys

Keyword.has_key?(module.__info__(:functions), func)
# => true

检查功能是否存在特定的arity

要查看arity,我们可以使用:erlang.function_exported/3

:erlang.function_exported(Map, :keys, 1)         # => true
:erlang.function_exported(Map, :keys, 2)         # => false

答案 1 :(得分:0)

在编译时,可以使用Module.defines?/2

defmodule M do
  __MODULE__ |> Module.defines?({:keys, 1})
end

在运行时,这将导致:

Map |> Module.defines?({:keys, 1})
     
    

**(ArgumentError)无法调用模块defines?上的Map,因为它已经编译了

(elixir) lib/module.ex:1169: Module.assert_not_compiled!/2
(elixir) lib/module.ex:753: Module.defines?/2
  

运行时的最短变体是:

iex(59)> Map.__info__(:functions)[:get]           
#⇒ 2 # minimal arity, truthy
iex(60)> Map.__info__(:functions)[:nonexisting]
#⇒ nil # no such function, falsey
iex(61)> !!Map.__info__(:functions)[:get]      
#⇒ true # erlang style
iex(62)> !!Map.__info__(:functions)[:nonexisting]
#⇒ false # erlang style

答案 2 :(得分:0)

像这样使用Kernel.function_exported?/3

function_exported?(List, :to_string, 1)
# => true