2016-05-06 11 views
2

私はモジュールがSilentDefinerであるとしましょう。その属性に基づいて、Silentの2つの関数を定義したいと思います。私に説明してみましょう:エリキシルに属性に基づいて関数を定義する方法は?

defmodule Silent do 
    @function_names [:a, :b, :c] 

    use Definer 
end 

defmodule Definer do 
    defmacro __using__(_) do 
    quote do 
     Enum.each(@function_names, fn(n) -> 
     def unquote(n)() do # line 5 
      IO.puts "a new method is here!" 
     end 
     end) 
    end 
    end 
end 

しかし、私はundefined function n/0 on line 5を持っているので、このアプローチは、実際には動作しません。どのようにして目的の機能を実装できますか?

+0

私はこのユースケースが何であるか知りたいです。あなたは何らかの貧しい人のインターフェースをしようとしていますか?もしそうなら、Elixirのプロトコルを見てください。http://elixir-lang.org/getting-started/protocols.html –

答えて

1

あなたはquoteunquoteフラグメントを注入できるようにするDefiner.__using__/1quoteunquote: falseを渡す必要があります。

defmodule Definer do 
    defmacro __using__(_) do 
    quote unquote: false do 
     Enum.each(@function_names, fn(n) -> 
     def unquote(n)() do # line 5 
      IO.puts "a new method is here!" 
     end 
     end) 
    end 
    end 
end 

defmodule Silent do 
    @function_names [:a, :b, :c] 

    use Definer 
end 

Silent.a 
Silent.b 
Silent.c 

プリント

a new method is here! 
a new method is here! 
a new method is here! 

同様のケースはまた、あなたがquoteにいくつかの変数を注入し、unquote断片を作成するには、両方たい場合bind_quotedを使用する方法を言及Kernel.SpecialForms.quote/2 docsに詳細に記載されています。

+0

ありがとうございます!!! – asiniy

関連する問題