2016-07-22 7 views
1

私は__using__の2つのバージョンを持っていますが、最初のバージョンは期待したものとは異なる動作をします。このコードは正しく動作しません(実際には何もインポートされません)。エリクシール引用符/クォートとマクロの動作

defmodule SomeModule do 
    defmacro __using__(opts \\ []) do 
    quote do 
     opts = unquote(opts) 
     if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do 
     import MyModuleOne 
     else 
     import MyModuleTwo 
     end 
    end 
    end 
end 

そして、これが作業バージョンである、しかし、私は2つの別々のquoteの部分を持っ好きではありません。

defmodule SomeModule do 
    defmacro __using__(opts \\ []) do 
    if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do 
     quote do 
     import MyModuleOne 
     end 
    else 
     quote do 
     import MyModuleTwo 
     end 
    end 
    end 
end 

正しく動作するには最初の書き換えはどうすればよいですか?

答えて

4

これは難しい問題です。理由を理解するために私をしばらく時間がかかりました...

マクロが完全に有効であり、エリクサーがと正確に動作することを確認してから、と伝えてください。

投稿した2つのマクロを展開しようとしたところ、同じ結果が得られました。つまり、正しいものがインポートされています。しかし、それが期待どおりに機能しないのはなぜですか?ここで

そのインポート/ 2を注意することが重要である理由、

であることimport

のためのドキュメントから字句

であると私はあなたに2例

を表示してみましょう
iex(1)> import Enum, only: [into: 2] 
Enum 
iex(2)> into [a: 1], %{} 
%{a: 1} 
iex(3)> 

および...

iex(1)> if true do 
...(1)> import Enum, only: [into: 2] 
...(1)> end 
Enum 
iex(2)> into [a: 1], %{} 
** (CompileError) iex:2: undefined function into/2 

インポートは唯一あなたがそれを書いた句の内部で有効になります:)

+0

えっ、あなたは右:)他の機能とすることをチェックしている - を確認:) – kovpack

関連する問題