2015-10-10 16 views
9

この投稿を参照してください:How to create a dynamic function name using Elixir macro?エリクシールマクロ:動的アリティを持つ関数を定義する方法

上記のポストは、マクロを引数なしで関数を生成する方法を尋ねましたが、いくつかの引数を使って関数を生成する方法を知りましたか?

マクロwarpがあると仮定し、私はちょうどのようなコードを書くことができます:

warp fun, [args], :ok 

し、それはのようなコードを生成します。

fun(args), do: :ok 
+0

I ' 'unquote_splicing 'についてのドキュメントを見つけるのに十分なほど難しい。このタイトルの変更は、私のような将来のGoogle社員にとって役立つかもしれません。 – nicooga

答えて

9

あなたは、引数の動的なリストを生成したい場合は、あなたがこのようなunquote_splicingを使用する必要があります。

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

その後

を生成
warp :foo, [a, b], {:ok, a, b} 

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

あなたはそれが

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

を生成することを呼び出す場合にもunquote_splicingせずにこのようなマクロを定義して、ちょうどdefに組み合わせた名前と引数をダウン渡すことができます。

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

これは、あなたがする必要があることを意味defを呼び出すのと同じようにwarpを呼び出します。

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

ここでは非常に単純な例です:

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 

これをIEXで実行すると、

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

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

関連する問題