Tôi có macro xác định mô-đun như vậy.Macro Elixir và bind_quoted
defmodule Bar do
def bar do
IO.puts "I am #{inspect __MODULE__}"
end
end
defmodule MacroFun do
defmacro define_module(name) do
quote do
defmodule unquote(name) do
import Bar
def foo do
bar
IO.puts "I am #{inspect __MODULE__}"
end
end
end
end
end
defmodule Runner do
require MacroFun
def run do
MacroFun.define_module Foo
Foo.foo
end
end
Runner.run
Kết quả của hoạt động này là:
I am Bar
I am Runner.Foo
nào có ý nghĩa; MacroFun.define_module
được gọi trong Runner.run
do đó mô-đun đã được xác định và do đó được lồng trong mô-đun Runner
.
Nhưng bây giờ nếu tôi thay đổi MacroFun.define_module
sử dụng :bind_quoted
tùy chọn:
defmacro define_module(name) do
quote bind_quoted: [name: name] do
defmodule name do
import Bar
def foo do
bar
IO.puts "I am #{inspect __MODULE__}"
end
end
end
end
Sản lượng lúc này là:
I am Bar
I am Foo
Tại sao ??
Wow, đó là khá tinh tế, nhưng có ý nghĩa. Tóm lại để chắc chắn rằng tôi hiểu: khi 'bind_quoted' được sử dụng, sau đó' name' là unquoted _outside_ phần thân ('do'..'end') của báo giá. Nhưng khi 'bind_quoted' không được sử dụng, thì' name' được bỏ qua một cách rõ ràng bên trong trích dẫn. – cjbottaro
Trích dẫn Heisenberg từ Breaking Bad: "Bạn đúng là chết tiệt". –