Sto sperimentando con Macro in elisir. Pertanto, il codice che sto per mostrare dovrebbe essere fatto con semplici funzioni ma ... sto sperimentando!Espansione macro in elisir: come definire 2 macro con una utilizzando l'altra?
Voglio definire 2 macro (A e B) e fare A uso B per sperimentare l'espansione delle macro. Quando uso A, viene visualizzato un errore di compilazione in cui si dice che la funzione B è indefinita.
Ecco il codice:
defmodule MyMacros do
defmacro print_expr(expr) do
quote do
IO.puts(unquote(expr))
end
end
defmacro print_hashes_around(expr) do
quote do
IO.puts "###"
print_expr(unquote(expr))
IO.puts "###"
end
end
end
defmodule MyModule do
require MyMacros
def my_print(expr) do
MyMacros.print_hashes_around(expr)
end
end
MyModule.my_print("hello world")
E qui è l'errore di compilazione:
macro_test.exs:17: warning: redefining module MyModule
** (CompileError) macro_test.exs:21: function print_expr/1 undefined
(stdlib) lists.erl:1336: :lists.foreach/2
macro_test.exs:17: (file)
(elixir) lib/code.ex:307: Code.require_file/2
Il mio modo di (mis) capire le cose:
- Con MyMacros richiedono, il modulo MyModule dovrebbe conoscere l'esistenza di entrambe le macro. Pertanto dovrei essere in grado di utilizzare qualsiasi macro.
- Quando print_hashes_around viene espanso in MyModule, il compilatore dovrebbe trovare che print_expr è anche una macro. Pertanto, dovrebbe verificarsi un'altra espansione.
- Ciò che sembra accadere è che la seconda espansione non avviene. Pertanto il compilatore cerca una definizione di funzione che non esiste.
Ho ragione?
Come suggerito nel gioco, il prefisso print_expr
con MyMacros.
lo corregge. Ancora non capisco perché. MyModule
richiede MyMacros
quindi entrambe le macro dovrebbero essere conosciute ed espandibili ... Quando guardo la definizione di unless
, utilizza if
, non Kernel.if
.
Grazie José, è sorprendente per ottenere una risposta dalla lingua Creatore stesso! – svarlet