Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros Elixir:生成捕获所有函数调用_Macros_Elixir - Fatal编程技术网

Macros Elixir:生成捕获所有函数调用

Macros Elixir:生成捕获所有函数调用,macros,elixir,Macros,Elixir,我有一个宏,它将catch all函数放在模块的末尾,因此生成的模块类似于: defmodule Module1 do <module body> ## Generated catch-all functions def fun1(_, _), do: :ok ## ..more catch-all functions...## end ## of module 在模块的主体中 我想在生成catch-all函数之前,我可以遍历模块的主体AST并对函数签名进行

我有一个宏,它将catch all函数放在模块的末尾,因此生成的模块类似于:

defmodule Module1 do
   <module body>
   ## Generated catch-all functions
   def fun1(_, _), do: :ok
   ## ..more catch-all functions...##
end ## of module
在模块的主体中

我想在生成catch-all函数之前,我可以遍历模块的主体AST并对函数签名进行一些分析,但这似乎需要做很多工作。还有其他方法吗?

(我想您知道这个解决方案,但回答这个问题可能对其他SO用户有用:)

正如José所说,在代码中隐藏太多内容不是一个很好的做法,因为这可能会导致意外(隐藏的代码可能会做一些你不希望做的事情),甚至会限制你(在这种特殊情况下,如果你没有明确的catchall,你无法摆脱它……)

我认为最好的方法是显式地使用宏来生成所有样板代码。调用宏的一行代码没有样板文件那么多;)

实施示例:

我们可以退一步问一下,为什么要自动定义catch-all子句?请记住显式几乎总是比隐式好。我的用例是生成一个具有大约10个回调的模块。它是一个SAX解析器,处理XML事件,根据解析器在更改中使用的系统状态切换处理程序。每个处理程序只应处理某些SAX事件(由模块的创建者描述),所有其他事件由默认处理程序处理。所有处理程序都是相同的样板代码,所以我认为生成它是有意义的。看起来GenServer也在做类似的事情,因为它为所有gen_服务器回调生成捕获所有,但允许用户覆盖它们。是的,我认为GenServer的行为是你能做的最明智的事情。提供默认实现,但是,如果覆盖它,则需要显式地提供catch all。你认为呢?在GenServer的情况下,我仍然希望保留最初生成的catch all子句,只是将其作为回调的最后一个子句
def MyServer确实使用GenServer end{:ok,pid}=GenServer.start_link(MyServer,100)send pid,:hello
:hello,但是:
def MyServer确实使用GenServer def handle_info(:my_msg,state)do IO.put:my_msg{:noreply,state}end{:ok,pid}=GenServer.start\u link(MyServer,100)send pid,:hello
我将获得“no function子句”异常,对不起,无法正确获取格式:-(当然,一行程序是一个好主意,但是,在我看来,对于某些情况,它可能仍然太多。在我的情况下,所有捕获都必须在模块中,无论是生成的还是手动定义的。想象一下,SAX解析器只处理特定类型的XML事件,比如具有“message”的“element\u start”和“element\u end”事件作为一个名字。所有其他活动(目前为6项,可能会更多)必须传递给默认处理程序。根据您的建议,我必须手动添加多达6行的catch all。这不是什么大问题,但听起来像是可以避免的不必要的工作。下一个仍然清晰易懂的方法是只使用一个函数并使用模式匹配。这样,您只需要使用一个catch all li氖。
   def fun1(arg1, arg2), do: ...