2015-10-10 12 views
9

consultare questo post: How to create a dynamic function name using Elixir macro?.Macro elisir: come definire la funzione con aritm dinamico

Il post precedente ha chiesto come utilizzare la macro per generare la funzione senza argomenti, ma mi chiedo come generare funzioni con alcuni argomenti?

assumere esiste una macro warp, ho potuto solo scrivere codice come:

warp fun, [args], :ok 

e poi generare il codice come:

fun(args), do: :ok 
+0

I' È abbastanza difficile trovare documenti su'unquote_splicing'. Il cambio di titolo può aiutare i futuri googler come me. – nicooga

risposta

9

Se si desidera generare un elenco dinamico di argomenti, è necessario utilizzare unquote_splicing come questo:

defmacro warp(name, argument_names, code) do 
    quote do 
    def unquote(name)(unquote_splicing(argument_names)) do 
     unquote(code) 
    end 
    end 
end 

Poi più tardi

warp :foo, [a, b], {:ok, a, b} 

che genera

def foo(a, b), do: {:ok, a, b} 

se si chiama che produrrà

foo(1, 2) 
# {:ok, 1, 2} 

È inoltre possibile definire la macro come questo senza unquote_splicing e proprio tramandare il nome combinato e gli argomenti a def:

defmacro warp(name_and_args, do: code) do 
    quote do 
    def unquote(name_and_args) do 
     unquote(code) 
    end 
    end 
end 

Ciò significa che è necessario invocare warp come si farebbe invocare def, ad esempio:

warp foo(a, b), do: {:ok, a, b} 
1

Ecco un esempio molto semplice:

defmodule SomeMacro do 
    defmacro warp(name, status) do 
    quote do 
     def unquote(name)(args) do 
     {unquote(status), Enum.join(args, " - ")} 
     end 
    end 
    end 
end 

defmodule SomeModule do 
    require SomeMacro 
    SomeMacro.warp :something, :ok 
end 

E se lo si esegue in IEX in questo modo:

iex(1)> SomeModule.something([1,2,3]) 
{:ok, "1 - 2 - 3"} 

iex(2)> SomeModule.something(["one", "two", "three"]) 
{:ok, "one - two - three"} 

Problemi correlati