【发布时间】:2015-05-09 21:25:24
【问题描述】:
我发现Kernel.apply/3 允许通过将方法指定为原子来动态调用模块中的公共方法,例如result = apply(__MODULE__, :my_method, [arg]) 转换为 result = my_method(arg)
让我感到困惑的是调用私有方法的方式;给定这样的代码:
defmodule MyModule do
def do_priv(atom, args) when is_list(args) do
apply(__MODULE__, atom, args)
end
# (change defp => def, and this all works)
defp something_private(arg), do: arg #or whatever
end
我希望MyModule.do_priv(:something_private, [1]) 是允许的,因为它是从模块内调用私有方法。我可以理解 Elixir 在底层使用 Erlang 的 apply/3,所以这种方法可能不会让我们到达那里。
我也尝试过使用 Code.eval_quoted/3 方法,但它似乎甚至无法调用硬编码的私有方法(因此没有时间手动构建 AST,而不是使用 quote do 作为下面 - 虽然如果有人看到如何使这项工作,这是一个选项):
defmodule MyModule do
def do_priv_static do
something_private(1) #this works just fine
end
def do_priv_dynamic do
code = quote do
something_private(1)
end
Code.eval_quoted(code, [], __ENV__) #nope. fails
end
defp something_private(arg), do: arg #or whatever
end
同样,它是从包含模块中访问私有函数的,所以我希望它是允许的。可能我只是不明白eval_quoted 的__ENV__ 参数
目前唯一可行的解决方案是将defp 更改为def,这是我个人代码的一个很好的解决方案;但由于我编写的代码支持其他关心的程序员,我想找到一个解决方案。
我对其他方法持开放态度,但我个人对如何实现这一点感到困惑。
【问题讨论】:
标签: elixir