【问题标题】:How to “splat” the function arguments for dynamically created function如何为动态创建的函数“喷溅”函数参数
【发布时间】:2018-05-22 09:00:45
【问题描述】:

我正在模块中生成一些函数:

defmodule M do
  funs = [do_it: [:arg1, :arg2]]

  Enum.each(funs, fn {name, args} ->
    args = Enum.map(args, & {&1, [], Elixir})
    def unquote(name)(unquote(args)),
      do: IO.inspect(unquote(args))
  end)
end

问题是生成的函数显然接受一个参数,即大小为 2 的列表:

▶ M.__info__(:functions) 
#⇒ [do_it: 1]

目标是动态声明函数接受两个参数。在 ruby​​ 术语中,这将是 unsplat 参数列表。

是否有可能在不对{:do_it, blah, [[ list of arguments ]]} 生成的 AST 进行模式匹配并手动展平列表的情况下完成此操作?

【问题讨论】:

    标签: macros elixir metaprogramming


    【解决方案1】:

    您可以使用Kernel.SpecialForms.unquote_splicing/1args 列表中“拼接”:

    defmodule M do
      funs = [do_it: [:arg1, :arg2], do_it: [:arg1, :arg2, :arg3]]
    
      Enum.each(funs, fn {name, args} ->
        def unquote(name)(unquote_splicing(args)), do: :ok
      end)
    end
    
    iex(1)> M.__info__(:functions)
    [do_it: 2, do_it: 3]
    

    【讨论】:

      猜你喜欢
      • 2019-05-09
      • 2021-02-27
      • 1970-01-01
      • 1970-01-01
      • 2023-01-04
      • 2019-02-09
      • 2014-07-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多