Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/elixir/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Macros 如何使用映射参数动态生成Phoenix控制器函数?_Macros_Elixir_Phoenix Framework - Fatal编程技术网

Macros 如何使用映射参数动态生成Phoenix控制器函数?

Macros 如何使用映射参数动态生成Phoenix控制器函数?,macros,elixir,phoenix-framework,Macros,Elixir,Phoenix Framework,所以我使用Phoenix 1.3,我创建了一个宏来生成一个函数并将其注入控制器 根据我传入的数字,我希望它生成一个包含许多参数的映射,这些参数被命名为“id1”、“id2”等等,一直到“id#{number}”。此映射将与常见的Phoenix“conn”一起作为参数列表的一部分 所以我想生成一个这样的方法来匹配模式,并且可以执行“一些东西”: def index(conn, %{"id1" => id1, "id2" => id2}) do # some stuff end 当

所以我使用Phoenix 1.3,我创建了一个宏来生成一个函数并将其注入控制器

根据我传入的数字,我希望它生成一个包含许多参数的映射,这些参数被命名为“id1”、“id2”等等,一直到“id#{number}”。此映射将与常见的Phoenix“conn”一起作为参数列表的一部分

所以我想生成一个这样的方法来匹配模式,并且可以执行“一些东西”:

def index(conn, %{"id1" => id1, "id2" => id2}) do
  # some stuff
end
当我调用宏
create\u some\u function\u by\u number(“index”,2)

我的宏看起来像:

defmacro create_some_function_by_number(name, num) do
    params =
      for n <- 1..num, do: %{"id#{n}" => Macro.var(:"id#{n}", nil)}
      |> Map.new

    quote do
      def unquote(:"#{name}")(unquote(Macro.escape(params)) do
         # some code here for the index action
      end
    end
  end
defmacro创建一些函数
params=
对于n Macro.var(:“id{n}”,nil)}
|>新地图
引述
def unquote(:“#{name}”)(unquote(Macro.escape(params))do
#这里有一些索引操作的代码
结束
结束
结束
1) 我如何将“conn”注入函数头,以便它可以与模式匹配


2) 这是创建要与模式匹配的映射的正确方法吗?

虽然您可以用这种方式使用宏,但您可能不应该这样做。以下是一个带有注释的工作解决方案:

defmodule MyMacro do
  defmacro create_some_function_by_number(name, num, do: block) do
    params =
      for n <- 1..num do
        {"id#{n}", Macro.var(:"id#{n}", nil)}
      end

    # We can't call Macro.escape because it is for escaping values.
    # In this case, we have a mixture of values "id#{n}" and
    # expressions "Macro.var(...)", so we build the map AST by hand.
    pattern =
      {:%{}, [], params}

    conn =
      Macro.var(:conn, nil)

    quote do
      def unquote(:"#{name}")(unquote(conn), unquote(pattern)) do
        unquote(block)
      end
    end
  end
end

defmodule MyExample do
  import MyMacro

  create_some_function_by_number :index, 2 do
    {conn, id1 + id2}
  end
end

IO.inspect MyExample.index(:conn, %{"id1" => 1, "id2" => 2})
defmodule MyMacro do
defmacro创建一些函数
params=

对于n来说,虽然您肯定可以用这种方式使用宏,但您可能不应该这样做。以下是一个带有注释的工作解决方案:

defmodule MyMacro do
  defmacro create_some_function_by_number(name, num, do: block) do
    params =
      for n <- 1..num do
        {"id#{n}", Macro.var(:"id#{n}", nil)}
      end

    # We can't call Macro.escape because it is for escaping values.
    # In this case, we have a mixture of values "id#{n}" and
    # expressions "Macro.var(...)", so we build the map AST by hand.
    pattern =
      {:%{}, [], params}

    conn =
      Macro.var(:conn, nil)

    quote do
      def unquote(:"#{name}")(unquote(conn), unquote(pattern)) do
        unquote(block)
      end
    end
  end
end

defmodule MyExample do
  import MyMacro

  create_some_function_by_number :index, 2 do
    {conn, id1 + id2}
  end
end

IO.inspect MyExample.index(:conn, %{"id1" => 1, "id2" => 2})
defmodule MyMacro do
defmacro创建一些函数
params=

对于n,使用宏听起来像是过早优化。你能通过在params映射中迭代元组来解决你的问题吗?@J.RandomCoder-你有关于“在params映射中迭代元组”的链接、片段或进一步的细节吗?另外,我还想了解更多关于元编程的知识,所以我想知道这个问题的答案?我的意思是,您可以在运行时动态地响应映射中的“项”(元组)数量,而不是在编译时为任何有意义的参数定义函数。无论第一个参数中有多少个元组,下面的代码段都可以工作:
Enum.map(%%{“id1”:23,“id2”:42},fn{key,value}->IO.put(“{key}:{value}”)end)
。我希望在函数头上进行精确的模式匹配,因为这似乎也能让我更轻松地利用操作回退进行错误处理。因此,如果它不匹配
def some_dynamic_fund(conn,%%“id1”=>id1,“id2”=>id2}=params),请执行:“hello”
,那么它自然会返回错误。使用宏听起来像是过早优化。你能通过在params映射中迭代元组来解决你的问题吗?@J.RandomCoder-你有关于“在params映射中迭代元组”的链接、片段或进一步的细节吗?另外,我还想了解更多关于元编程的知识,所以我想知道这个问题的答案?我的意思是,您可以在运行时动态地响应映射中的“项”(元组)数量,而不是在编译时为任何有意义的参数定义函数。无论第一个参数中有多少个元组,下面的代码段都可以工作:
Enum.map(%%{“id1”:23,“id2”:42},fn{key,value}->IO.put(“{key}:{value}”)end)
。我希望在函数头上进行精确的模式匹配,因为这似乎也能让我更轻松地利用操作回退进行错误处理。因此,如果它不匹配
def some_dynamic_fund(conn,%%{“id1”=>id1,“id2”=>id2}=params),请执行:“hello”
,那么它自然会返回错误。