2017-09-16 4 views
1

私は、呼び出しモジュールに関数を注入する単純なマクロを持っています。エリキシルの引用ブロックの外側の関数を定義します。

defmodule MyModule do 
    defmacro __using__(_opts) do 
    quote do 
     def run do 
     IO.puts "Hello world" 
     end 
    end 
    end 
end 

これは意図した通りですが、run関数がquoteブロック内にネストされているため、ExDocを使用してドキュメントを追加できません。私はまた、私はコードがより見栄えが良いと感じるように、実行機能を外部に定義したいと思います。このようなもの:

defmodule MyModule do 
    def run do 
    IO.puts "Hello world" 
    end 

    defmacro __using__(_opts) do 
    quote do 
     # Some code to inject the run function 
    end 
    end 
end 

どうすればよいですか?さらに、ネストされた関数に対してExDocを使用してドキュメントを追加するにはどうすればよいですか?

+0

ドキュメントを 'MyModule.run'に追加するか、' use MyModule'を実行するモジュールに注入する 'run'関数に表示しますか? – Dogbert

+0

@DogbertドキュメントをMyModule.runと 'use MyModule'モジュールに追加したい –

+0

@Dogbertネストされた実行関数用のドキュメントを定義すると、ドキュメントは元のモジュールではなく、目的のモジュールで取得されます。 –

答えて

2

quoteの中にdefdelegateを使用し、メインモジュールにrunを定義することができます。

defmodule MyModule do 
    @doc """ 
    Prints "Hello world" 
    """ 
    def run do 
    IO.puts "Hello world" 
    end 

    defmacro __using__(_opts) do 
    quote do 
     defdelegate run, to: MyModule 
    end 
    end 
end 

defmodule A do 
    use MyModule 
end 

A.run/0MyModule.run/0にユーザーを指しますデフォルトでは、自動生成されたドキュメントを取得します。これは、必要に応じてdefdelegateの前に@doc ""を追加することによってカスタマイズできます。

iex(1)> MyModule.run 
Hello world 
:ok 
iex(2)> A.run 
Hello world 
:ok 
iex(3)> h(MyModule.run) 

            def run() 

Prints "Hello world" 

iex(4)> h(A.run) 

            def run() 

See MyModule.run/0. 
+0

ありがとうございました。これは動作しますが、実行関数に引数がある場合はどうなりますか? –

+0

FWIW、['Module.add_doc/6'](https://hexdocs.pm/elixir/Module.html#add_doc/6)。 – mudasobwa

+0

@MohideenImranKhanあなたが 'def add(a、b)...'と言っていれば、 'defdelegate'は' defdelegate add(a、b)、to:MyModule'になります。 – Dogbert

関連する問題