2017-09-16 2 views
1

Ich habe ein einfaches Makro, das eine Funktion in das aufrufende Modul einfügt.Funktion außerhalb des Angebotsblocks in Elixir definieren

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

Dies funktioniert soll als aber aufgrund der Tatsache, dass die Lauffunktion innerhalb des Kursblock verschachtelt ist, ich bin nicht in der Lage Dokumentation hinzufügen ExDoc verwenden. Ich möchte auch die Run-Funktion außerhalb definieren, da ich fühle, dass der Code besser aussieht. So etwas wie dieses:

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 

Wie gehe ich dabei vor? Wie füge ich außerdem Dokumentation hinzu, die ExDoc für eine geschachtelte Funktion verwendet?

+0

Haben Sie in der Dokumentation zu 'MyModule.run' hinzufügen möchten oder haben Sie es in der' run' Funktion, die Sie in das Modul injizieren angezeigt werden soll, die 'MyModule' nicht verwendet? – Dogbert

+0

@Dogbert Ich möchte die Dokumentation zu MyModule.run hinzufügen und in dem Modul, das MyModule verwendet –

+0

@Dogbert Wenn ich die Dokumente für die geschachtelte Ausführung definieren, bekomme ich die Dokumentation im Zielmodul, aber nicht das ursprüngliche Modul. –

Antwort

2

Sie können defdelegate innerhalb der quote verwenden und dann run im Hauptmodul definieren.

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/0 wird ein Auto erzeugt doc standardmäßig erhalten, die den Benutzer auf MyModule.run/0 verweisen. Dies kann angepasst werden, indem bei Bedarf ein @doc "" vor defdelegate hinzugefügt wird.

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

Vielen Dank. Das funktioniert aber, wenn die run-Funktion Argumente hat? –

+0

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

+0

@MohideenImranKhan Wenn Sie 'def add (a, b) ...' gesagt haben, wäre 'defdelegate'' defdelegate add (a, b), zu: MyModule'. – Dogbert

Verwandte Themen