Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
604 views
in Technique[技术] by (71.8m points)

erlang - 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

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?

question from:https://stackoverflow.com/questions/13230965/how-to-call-a-method-dynamically-in-elixir-by-specifying-both-module-and-method

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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])

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)

Edit: 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])

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...