2016-12-09 16 views
1

ここで興味深い質問があります。エリクサーのモジュール属性のドキュメント、つまりhttp://elixir-lang.org/getting-started/module-attributes.htmlの下部に、ExUnitのようにメソッド注釈として使用できることが書かれています。モジュールの注釈をメソッドの属性として使用する

残念ながら、これを達成する方法やExUnitコードを調べる方法に関する情報は、基本的に私には分かりません。私は属性に最も近い方法を決定して、何らかの形で関連付けられている(間違っているかもしれない)と言う必要があるようです。

私はこれについて学ぶためにどこに見えるかもしれませんか?

+1

このページを見ましたか? http://elixir-lang.org/docs/master/ex_unit/ExUnit.Case.htmlより具体的には、このページのこのセクションはあなたの質問に関連しているようです:http://elixir-lang.org/docs/master/ex_unit/ ExUnit.Case.html#module-tagsこのページにはあなたに不明な点がありますか?あなたの質問は私にはあまり明確ではありません。 –

+0

私はあなたのショーを知っていませんね、ExUnitには@tagsが付いていて、関数の注釈として機能しています。私は実際にはそれをいろいろと使いこなすことを解決しました。そして今、コンパイル時に実際にこれらのアノテーションで有用なことができたという別の問題があります。ここで私の周りに支払う:https://github.com/chrisjowen/annotatable – Owen

+0

あなたが知りたいことがきわめて明確ではないことを看板として私のコメントをしてください。 –

答えて

2

このように動作します。ソースコードExUnit.Caseを見てください。

最初に、__using__マクロを調べます。これは、テストケースで使用するときに最初に呼び出されるためです。特に、これは@tagと蓄積されたとして、より多くの属性の束を登録here

Enum.each [:ex_unit_tests, :tag, :describetag, :moduletag, :ex_unit_registered], 
     &Module.register_attribute(__MODULE__, &1, accumulate: true) 

に注意してください。 Module.register_attribute/3のドキュメントを読んで、anytime属性が呼び出されると、その値が以前の属性のリストに追加されることを意味します。

そしてtest/3マクロ、特にhere

quote bind_quoted: [var: var, contents: contents, message: message] do 
    name = ExUnit.Case.register_test(__ENV__, :test, message, []) 
    def unquote(name)(unquote(var)), do: unquote(contents) 
end 

ExUnit.Case.register_test/4への呼び出しを注意。それを見ると、特別にhere

tag = Module.delete_attribute(mod, :tag) 

それはここまでのタグを取得し、それらを削除します。そしてタグ、およびテストの名前を有することにより、別の属性内部タグと一緒にテストを保存する(here

test = %ExUnit.Test{name: name, case: mod, tags: tags} 
Module.put_attribute(mod, :ex_unit_tests, test) 

を呼び出します。

そして最後に

、ここ

@doc false 
    defmacro __before_compile__(_) do 
    quote do 
     def __ex_unit__(:case) do 
     %ExUnit.TestCase{name: __MODULE__, tests: @ex_unit_tests} 
     end 
    end 
    end 

__ex_unit__/1は、各ケース内のテストの情報を取得するためにExUnit.Runner.run_case/3に呼び出される関数を注意してください。

ポイントが表示されますか?あなたのマクロ呼び出しの中で累積された属性を使用して、常にその属性の現在の値を取得し、それをクリアし、その値で必要なものを実行する関数を使用します。

詳細が必要な場合は、十分に明確であり、コメントを削除したいと思います。

PS。私はちょうどこれを見つけるためにソースコードを読んでいます。それがどのように機能するか知ることはエキサイティングでした。

+0

私はこれがかなり多くのスポットであるので、答えを受け入れる。私は実際にこれを理解して、どのような方法にも注釈を付けるために小さなライブラリをノックアップしました。あなたが言ったように、重要な部分は蓄積されました:register_attributeのタグ。その素晴らしいエリクシールは実際にメソッドの注釈をサポートしていませんが、言語はちょうどあなた自身でそれを行うのに十分なハッキング可能です:) – Owen

+1

他に誰かがこれに興味を持っていれば、 ExUnitでは、テストマクロが呼び出され、その前に定義されている属性が取得され、削除される必要があります。メソッドを定義する場合は、プラグインできるマクロは呼び出されませんが、幸いにも@on_defenition(https://hexdocs.pm/elixir/Module.htmlを参照)を使用できるモジュールライフサイクルメソッドがあります。 – Owen

関連する問題