例如,如果你有一个模块
defmodule Foo do
# lots of "unknown" functions
end如何为Foo创建包装器模块,如:
defmodule Bar do
# wrap all functions in Foo
end但在Bar中,我想在Foo中公开所有函数,但另外我想在每个函数中添加一些代码,特别是我想try/catch一个可以在任何Foo.Error异常中显示的特定错误……我想在不为Foo中的每个函数添加函数的情况下这样做,因为这会变得重复。
我能用宏做到这一点吗?
发布于 2019-12-04 18:15:00
AFAIU您希望通过复制类之间的继承逻辑来执行某种面向对象编程。但这并不是像Elixir这样的函数式编程语言的哲学,您可能已经知道了。
然而,如果这真的是你想要做的,我找到了this question,它使用元编程,旨在做一些与你正在寻找的事情相似的事情。不过,这看起来很复杂。
编辑:在我们进行了进一步的交谈之后,我更好地理解了你的问题。如果你想定义函数而不想重复太多,那么元编程是最好的选择!下面是一个简单的例子,说明如何通过元编程在一个模块中定义几个函数:
defmodule MyModule do
Enum.each ~w(method1 method2), fn(method_name) ->
def unquote(:"#{method_name}")(), do: unquote(method_name)
end
end我不想为Foo中的每个函数都添加一个函数,因为这会变得重复。,
,我想在Foo中为每个函数添加函数。
我想这就是我会做的,但你确定这会是重复的吗?
此外,您还可以使用Exceptional lib来帮助您编写更少的错误处理函数:)
发布于 2019-12-06 02:11:28
使用元编程的魔力,一切都是可能的(然而,这并不总是有意义的):
defmodule Bar do
Code.ensure_compiled(Foo)
for {func, arity} <- Foo.__info__(:functions) do
args = Macro.generate_arguments(arity, __MODULE__)
def unquote(func)(unquote_splicing(args)) do
Foo.unquote(func)(unquote_splicing(args))
rescue
Foo.Error -> handle_error()
end
end
end但是,这不适用于宏。
发布于 2019-12-05 10:54:14
这是def宏的一个很好的用法,但也一定要研究一下defedelegate。它允许您添加(委托)对其他/外部模块中函数的命名引用。
https://stackoverflow.com/questions/59173280
复制相似问题