2016-10-25 59 views
0

我需要我所有的模型來實現特定的協議。我現在的嘗試是一個MyApp.Convert模塊,這個宏定義:我怎樣才能同時爲多個模塊定義? (宏嘗試不工作)

defmodule ConvertMacro do 
    @moduledoc """ 
    All model structs need to implement the convert interface and must be added 
    here. 
    """ 

    defmacro defimpl_convert_for(modules) do 
    Enum.map(modules, fn module -> 
     quote do 
     defimpl Units.Convert, for: unquote(module) do 
      require Units 

      def to_standard_metric(struct) do 
      Units.to_standard_metric_for_struct(unquote(module), struct) 
      end 

      def to_user_data(struct) do 
      Units.to_user_data_for_struct(unquote(module), struct) 
      end 
     end 
     end 
    end) 
    end 
end 

ConvertMacto.defimpl_convert_for([MyApp.User, MyApp.Block]) 

錯誤:

== Compilation error on file lib/protocols/units_convert.ex == 
** (UndefinedFunctionError) function ConvertMacro.defimpl_convert_for/1 is undefined or private. Did you mean one of: 

     * defimpl_convert_for/1 

    ConvertMacro.defimpl_convert_for([UdioDb.Block]) 
    (elixir) lib/kernel/parallel_compiler.ex:117: anonymous fn/4 in Kernel.ParallelCompiler.spawn_compilers/1 

(錯誤消息實際上是有點多餘)

有沒有辦法來實現我試圖去做,還是我只需要輸入一切呢?

+0

你可以請包括[MCVE](http://stackoverflow.com/help/mcve)或至少包括周圍的代碼和錯誤消息?當我們不知道如何調用這個宏以及錯誤是什麼時,很難弄清楚究竟發生了什麼錯誤。 – Dogbert

+0

@Dogbert發佈​​了帶有錯誤 –

+0

的完整代碼(請注意,您也可以將列表傳遞給'defimpl':https://github.com/elixir-lang/elixir/blob/03a7d744cc1ce7c3820ee60cafcf71b1bc7d5211/lib/elixir/test/elixir/protocol_test .exs#L183-L185) – Dogbert

回答

4

它實際上是因爲defimpl更簡單的支持它本身:

defimpl FooProtocol, for: [Foo, Baz, Bar] do 
    def protocol_function(x, y, z) do 
    @for.some_function(x, y, z) 
    end 
end 

@for模塊屬性允許您訪問該協議是爲實現該模塊。你可以在這裏看到例子:https://github.com/elixir-ecto/ecto/blob/master/lib/ecto/date_time.ex#L650-L662

+0

omg我對這個語言的最大暗戀<3(並且對於我不推薦RTFM而感到羞恥) –

+0

@ o_o_o--發現utf8,Elixir值得❤❤❤而不是<3 – mudasobwa

相關問題