2017-12-08 22 views
3

私はモジュール内の一部の機能を生成していますために「スプラット」関数の引数:どのように動的に作成された関数

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 

問題生成された関数は明らかに1つの引数、サイズ2のすなわちリストを受け入れています。

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

目標は、動的の引数を受け取る関数を宣言することです。ルビーの用語では、引数リストをunsplatするとになります。

{:do_it, blah, [[ list of arguments ]]}の結果のASTとパターンマッチングすることなくこれを達成し、手動でリストを平坦化する可能性はありますか?

答えて

6

あなたはargsリストに "スプライス" にKernel.SpecialForms.unquote_splicing/1を使用することができます。

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

これ!どうもありがとうございます。私はすでにそれを使用しています。 – mudasobwa

関連する問題