如何通过指定模块和方法名称在Elixir中动态调用方法? [英] How to call a method dynamically in Elixir, by specifying both module and method name?
问题描述
我想知道长生不老药中确切的方法名称是什么
I'd like to know what exactly a method name is in elixir:
array = [1,2,3]
module_name = :lists
method_name = :nth # this not working
module_name.method_name(1, array) # error, undef function lists.method_name/2
module_name.nth(1, array) # returns 1, module_name is OK. It's an atom
但是我可以在erlang中做几乎相同的事情:
But I can do almost the same thing in erlang:
A = [1,2,3].
X = lists.
Y = nth.
X:Y(1,A). # returns 1
我如何在长生不老药中做到这一点?
How can I do this in elixir?
推荐答案
您可以使用apply/3
,它只是对:erlang.apply/3
的包装.它只是调用给定的module
到arguments
的数组.
You can use apply/3
which is just a wrapper around :erlang.apply/3
. It simply invokes the given function
from the module
with an array of arguments
. Since you are passing arguments as the module and function names you can use variables.
apply(:lists, :nth, [1, [1,2,3]])
apply(module_name, method_name, [1, array])
如果您想了解有关elixir如何处理函数调用(以及其他所有内容)的更多信息,则应查看quote
和unquote
.
If you want to understand more about how elixir handles function calls (and everything else) you should take a look at quote
and unquote
.
contents = quote do: unquote(module_name).unquote(method_name)(1, unquote(array))
返回函数调用的谐音表示.
which returns the homoiconic representation of the function call.
{{:.,0,[:lists,:nth]},0,[1,[1,2,3]]}
You can unquote
the quoted function call with Code.eval_quoted/3
{value, binding} = Code.eval_quoted(contents)
这是一个使用Enum.fetch和var的示例.
here is an example using Enum.fetch along with a var.
quoted_fetch = quote do: Enum.fetch([1,2,3], var!(item));
{value, binding} = Code.eval_quoted(quoted_fetch, [item: 2])
这篇关于如何通过指定模块和方法名称在Elixir中动态调用方法?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!