Elixir macros and bind_quoted

前端 未结 2 659
悲哀的现实
悲哀的现实 2021-02-08 17:49

I have a macro that defines a module like so.

defmodule Bar do
  def bar do
    IO.puts \"I am #{inspect __MODULE__}\"
  end
end

defmodule MacroFun do

  defmac         


        
2条回答
  •  温柔的废话
    2021-02-08 18:27

    With this code you will see the correct values used to create the modules:

    require Logger
    
    defmodule Bar do
      def bar do
        IO.puts "I am #{inspect __MODULE__}"
      end
    end
    
    defmodule MacroFun do
    
      defmacro define_module(name) do
        quote do
          Logger.debug("#{inspect unquote(name)}")
          defmodule unquote(name) do
            import Bar
            Logger.debug("#{inspect unquote(name)}")
            def foo do
              bar
              IO.puts "I am #{inspect __MODULE__}"
            end
          end
        end
      end
    
      defmacro define_module2(name) do
        quote bind_quoted: [name: name] do
          defmodule name do
            import Bar
            Logger.debug("#{inspect name}")
            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
      def run2 do
        MacroFun.define_module2 Foo2
        Foo2.foo
      end
    
    end
    
    Runner.run
    Runner.run2
    

    Output:

    [warn]  Foo
    [warn]  Runner.Foo
    I am Bar
    I am Runner.Foo
    
    [warn]  Foo2
    I am Bar
    I am Foo2
    

提交回复
热议问题