简体   繁体   English

Elixir中的源代码生成

[英]Source code generation in Elixir

I'm currently learning/reading metaprogramming elixir 我正在学习/阅读元编程灵药
I managed to generate a function that puts it's name using macros: 我设法生成一个使用宏来放置它的名字的函数:

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

the result: 结果:

iex(1)> My.bar
bar
:ok

so this is great :) but I was wondering if it was possible to generate several functions using a Enum.each or something like that: 所以这很棒:)但我想知道是否有可能使用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

Is there a way of looping in order to generate source code ? 有没有一种循环方式来生成源代码? Thank you ! 谢谢 !

You could do it without using macros at all: 你可以在不使用宏的情况下完成它:

 defmodule My do

  @methods ~w|one two three|a

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

end

produces: 生产:

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

Or with a macro: 或者使用宏:

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

produces: 生产:

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

Note: We are passing the list directly to gen_funs rather than a sigil or a variable containing the list. 注意:我们将列表直接传递给gen_funs而不是sigil或包含列表的变量。 We must do this since macros receive their arguments quoted. 我们必须这样做,因为宏接收引用的参数。 This is why you must do the looping in the macro rather than the module using the macro. 这就是为什么你必须在宏中而不是使用宏的模块中进行循环。

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

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