繁体   English   中英

Elixir中的源代码生成

[英]Source code generation in Elixir

我正在学习/阅读元编程灵药
我设法生成一个使用宏来放置它的名字的函数:

defmodule MyMacros do
  defmacro fun_gen(name) do
    atom_name = elem(name, 0)
    str_name = atom_name |> to_string
    quote do
      def unquote(name) do
        IO.puts unquote(str_name)
      end
    end
  end
end

defmodule My do
  require MyMacros
  MyMacros.fun_gen(bar)
end

结果:

iex(1)> My.bar
bar
:ok

所以这很棒:)但我想知道是否有可能使用Enum.each或类似的东西生成几个函数:

defmodule MyMacros do
  defmacro fun_gen(name) do
    atom_name = elem(name, 0)
    str_name = atom_name |> to_string
    quote do
      def unquote(name) do
        IO.puts unquote(str_name)
      end
    end
  end
end

defmodule My do
  require MyMacros
  loop (~w(foo bar baz) do
    MyMacros.fun_gen(item)
  end
end

有没有一种循环方式来生成源代码? 谢谢 !

你可以在不使用宏的情况下完成它:

 defmodule My do

  @methods ~w|one two three|a

  for method <- @methods do
    def unquote(method)() do
      IO.puts unquote(method)
    end
  end

end

生产:

iex> My.one
one
iex> My.two
two

或者使用宏:

defmodule MyMacros do
  defmacro gen_funs(names) do
    for name <- names do
      quote do
        def unquote(name)() do
          IO.puts unquote(name)
        end
      end
    end
  end
end

defmodule My2 do
  require MyMacros
  MyMacros.gen_funs([:one, :two, :three])
end

生产:

iex> My2.one
one
iex> My2.two
two

注意:我们将列表直接传递给gen_funs而不是sigil或包含列表的变量。 我们必须这样做,因为宏接收引用的参数。 这就是为什么你必须在宏中而不是使用宏的模块中进行循环。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM