我一直在研究一个宏来动态生成匿名函数。该函数应该有 2 个子句。当满足保护条件时,第一个子句返回 TRUE。而第二个是默认值,如果与第一个子句不匹配,则返回 FALSE。例如:
fn
xfield when xfield > 2 -> true
_ -> false
end
Run Code Online (Sandbox Code Playgroud)
这是我的宏原型
defmacro condition_function(field, guard) do
clause1 = quote do: (unquote(field) when unquote(guard) -> true)
clause2 = quote do: (_ -> false)
fun_clauses = clause1 ++ clause2
{:fn, [], fun_clauses}
end
Run Code Online (Sandbox Code Playgroud)
问题是第一个子句永远不匹配。这是我在 Elixir 的 REPL 中测试宏时使用的输入:
iex(84)> myfield = quote do: xfield
{:xfield, [], Elixir}
iex(85)> myguard = quote do: xfield > 2
{:>, [context: Elixir, import: Kernel], [{:xfield, [], Elixir}, 2]}
iex(86)> myFun = Builder.condition_function(myfield, myguard)
#Function<6.50752066/1 in :erl_eval.expr/5>
iex(87)> myFun.(2)
false
iex(88)> myFun.(5)
false
Run Code Online (Sandbox Code Playgroud)
有什么建议么?
预先感谢,温贝托
感谢 Slack 频道人员的帮助和 CoderDennis 的提示,我解决了我的问题。
这是我的一个误解。我不需要使用宏。我只需要一个常规功能。
这是我的函数的最终版本,用于创建带有保护的匿名函数:
def anonym_function(field, constraint) do
clause1 = quote do: (unquote(field) when unquote(constraint) -> true)
clause2 = quote do: (_ -> false)
fun_clauses = clause1 ++ clause2
{fun, _} = Code.eval_quoted({:fn, [], fun_clauses})
fun
end
Run Code Online (Sandbox Code Playgroud)
抱歉我的误解:(