鉴于我的函数直接在头部进行模式匹配,有没有办法让我检查函数是否具有给定输入的匹配模式而不调用它?有点像match?
,但功能。我并不关心when
而我只关注元组内的原子或原子。
e.g。
def init(:ok) do
...
end
和
check(&init/1, :ok) # return true
check(&init/1, :other) # return false
我使用处理某些输入的函数列表修改GenServer中的状态,并忽略其他输入。每个函数都使用一个元组,一些状态,如果函数头匹配则返回修改后的状态,如果不匹配则返回状态。我现在有一个try / rescue包装函数,这不是很好。输入是可变长度元组,第一个元素是原子标识符。
答案 0 :(得分:1)
严格来说,这是不可能的。 Elixir.FunctionClauseError
只是底层erlang function_clause
runtime error的包装器。
检查是在运行中完成的,可以检查任何特定条款,但没有准备检查的条款列表。好的例子就是坐在你面前的贪婪的猫;你可能会尝试用苹果,胡萝卜甚至是回形针喂她,但除非你尝试过,否则不能说她是否会吃它。
另一方面,人们总是可以选择查询Module.__info__ :functions
。它以arity响应,因此可以检测并拒绝所有Elixir.UndefinedFunctionError
s。
但子句匹配是在运行时完成的,因此无法接收允许的子句列表。考虑一下条款可能是一个繁琐的守卫(when
,)显式参数(:ok
),它们甚至可能重叠。
正如它所述的问题:
check(&init/1, :ok) # return true
check(&init/1, :other) # return false
不过,有一个强力解决方案。我不推荐它,但它仍然可用:实现check
,因为调用该函数并从Elixir.FunctionClauseError
进行救援。
另外,请不要分享我是有这个建议的人。