2012-11-05 9 views
27

Mi piacerebbe sapere che cosa esattamente un nome del metodo è in elisir:Come chiamare dinamicamente un metodo in Elixir, specificando sia il nome del modulo che quello del metodo?

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 

Ma posso fare quasi la stessa cosa in Erlang:

A = [1,2,3]. 
X = lists. 
Y = nth. 
X:Y(1,A). # returns 1 

Come posso fare questo in elisir?

risposta

39

È possibile utilizzare apply/3 che è solo un involucro intorno a :erlang.apply/3. Semplicemente invokes the given function from the module with an array of arguments. Poiché si passano gli argomenti come nomi di moduli e funzioni, è possibile utilizzare variabili.

apply(:lists, :nth, [1, [1,2,3]]) 
apply(module_name, method_name, [1, array]) 

Se si vuole capire di più su come elisir gestisce le chiamate di funzione (e tutto il resto) si dovrebbe dare un'occhiata a quote e unquote.

contents = quote do: unquote(module_name).unquote(method_name)(1, unquote(array)) 

che restituisce la rappresentazione omoiconica della chiamata di funzione.

{{:.,0,[:lists,:nth]},0,[1,[1,2,3]]} 

È possibile unquote la chiamata di funzione citato con Code.eval_quoted/3

{value, binding} = Code.eval_quoted(contents) 

Edit: ecco un esempio utilizzando Enum.fetch insieme a una var.

quoted_fetch = quote do: Enum.fetch([1,2,3], var!(item));    
{value, binding} = Code.eval_quoted(quoted_fetch, [item: 2]) 
+0

Buono. Quindi il nome del metodo è un atomo. Ora penso che sia solo la sintassi che non ci permette di scrivere 'module.method' in elisir, giusto? – halfelf

+1

Credo che tu abbia ragione. Penso che l'unico modo per farlo funzionare sarebbe cambiare la sintassi per usare gli atomi quando si chiamano le funzioni del modulo (ad esempio ': lists.: Nth'). Preferirei semplicemente usare apply in casi come questo. – lastcanal

+0

Grazie. Questa risposta è molto utile. – halfelf