2017-12-08 6 views
3

I in das Modul einige Funktionen am Erzeugen:Wie „Klecks“ die Funktionsargumente für dynamisch erstellte Funktion

defmodule M do 
    funs = [do_it: [:arg1, :arg2]] 

    Enum.each(funs, fn {name, args} -> 
    args = Enum.map(args, & {&1, [], Elixir}) 
    def unquote(name)(unquote(args)), 
     do: IO.inspect(unquote(args)) 
    end) 
end 

Das Problem ist die erzeugte Funktion akzeptiert offensichtlich ein einziges Argument, nämlich eine Liste der Größe 2: Annahme zwei Argumente

▶ M.__info__(:functions) 
#⇒ [do_it: 1] 

Das Ziel ist, dynamisch die Funktion zu erklären. In der Rubin-Terminologie wäre es , um die Argumentliste aufzuheben.

Gibt es eine Möglichkeit, dies ohne Muster zu erreichen, das dem resultierenden AST für {:do_it, blah, [[ list of arguments ]]} entspricht und die Liste manuell abflacht?

Antwort

6

können Sie verwenden Kernel.SpecialForms.unquote_splicing/1 auf "Splice" in der args Liste:

defmodule M do 
    funs = [do_it: [:arg1, :arg2], do_it: [:arg1, :arg2, :arg3]] 

    Enum.each(funs, fn {name, args} -> 
    def unquote(name)(unquote_splicing(args)), do: :ok 
    end) 
end 
iex(1)> M.__info__(:functions) 
[do_it: 2, do_it: 3] 
+1

This! Ich danke dir sehr. Ich habe es sogar schon benutzt. – mudasobwa

Verwandte Themen