2015-09-09 2 views
6

Sto provando a scrivere una serie di macro che dovrebbero dipendere dalla conoscenza dello stesso modulo e quindi, sto cercando di evitare di passare esplicitamente questo modulo a ciascuna funzione (in realtà sto bene così, ma mentre sto imparando la lingua sto cercando di esplorare tutte le possibilità!).È possibile accedere dinamicamente al modulo tramite stringa o simbolo?

Così sto scrivendo (l'obiettivo è di accedere SomeOtherModule, o invocare SomeOtherModule.foo all'interno della funzione generato foo.)

defmodule MacrosUser do 
    use MyMacros, SomeOtherModule 
end 

defmodule MyMacros do 
    defmacro __using__(opts) do 
    {:__aliases__, _, module_path} = opts 
    quote do 
     def foo do 
     module_path 
     |> Enum.join(".") 
     |> apply(:foo, []) 
     end 
    end 
    end 
end 

Ma questo, ovviamente, non funziona come apply/3 aspettarsi un modulo e non una stringa o rappresentazione di simboli del nome del modulo.

Fondamentalmente, come dice il titolo, sto cercando un modo per farlo in modo che per una determinata stringa o simbolo acceda al modulo corrispondente o invochi una funzione di quel modulo.

Inoltre, so che è possibile accedere al modulo corrente tramite __MODULE__ in macro, ma sto cercando un modo per accedere a qualsiasi modulo esistente, non solo quello attuale.

+0

All'interno del contesto di 'MyMacros',' __MODULE__ == MyMacros ==: "Elixir.MyMacros" '. –

+0

Sì, lo so. Nell'esempio stavo cercando un modo per accedere a 'SomeOtherModule' che è passato all'hook' __using__'. Probabilmente dovrei aggiornare la domanda. – user2205259

risposta

11

Utilizzare Module.concat(module_path) invece di unire manualmente il percorso, poiché è destinato a questo scopo.

+3

Risposta perfetta. Vale anche la pena aggiungere la clausola di esclusione della responsabilità che gli sviluppatori dovrebbero evitare questo approccio quando possibile, in quanto l'elisir favorisce l'esplicito implicito. Inoltre, questo approccio potrebbe non essere sicuro in molte occasioni, il primo degli atomi e i nomi dei moduli sono spazzatura. –