2016-12-09 1 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에 호출되는 기능을 확인합니다.

포인트가 보입니까? 누적 된 속성을 사용하십시오. 매크로 호출 내에서 항상 속성의 현재 값을 가져 와서 지우고 그 값으로 원하는 모든 작업을 수행하는 함수를 사용하십시오. 매크로가 호출 될 때마다 항상 알 수 있기 때문입니다.

자세한 설명이 필요하면 의견이 분명하기를 바랍니다.

추신. 나는 이것을 알아 내기 위해 소스 코드를 읽었을 뿐이다. 그것이 어떻게 작동하는지 아는 것은 흥미로웠다.

+0

나는이 답변을 받아들입니다. 나는 실제로 이것을 알아 냈고 어떤 방법에 주석을 달기 위해 그 작은 도서관을 쓰러 뜨렸다. 당신이 말했듯이 중요한 부분은 누적되었다 : register_attribute의 태그. 꽤 좋은 그 엘릭서는 실제로 메소드 주석을 지원하지 않지만, 언어는 해킹만으로 충분히 해킹 할 수 있습니다 :) – Owen

+1

다른 사람들이 이것에 관심이 있다면 언급 할 것은 한 가지 더 있습니다. ExUnit은 테스트 매크로가 호출되어 그 전에 정의 된 속성을 검색하고 삭제해야합니다. 메소드를 정의하는 경우 플러그인 할 수있는 매크로는 호출되지 않지만 다행히도 @on_defenition (https://hexdocs.pm/elixir/Module.html 참조)을 사용할 수있는 모듈 라이프 사이클 메소드가 있습니다. – Owen

관련 문제