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 Elixir 1.3中的宏和模块属性_Macros_Elixir - Fatal编程技术网

Macros Elixir 1.3中的宏和模块属性

Macros Elixir 1.3中的宏和模块属性,macros,elixir,Macros,Elixir,Elixir 1.3.0-rc1编译器无法编译我的一个宏。 在《长生不老药1.2.6》中还可以 defmodule M do defmacro ifa(a, exp) do if (Macro.expand_once(a, __ENV__)), do: exp end end defmodule Foo do @flag true require M def main do M.ifa (@flag), do: IO.puts 123 end end

Elixir 1.3.0-rc1编译器无法编译我的一个宏。 在《长生不老药1.2.6》中还可以

defmodule M do
  defmacro ifa(a, exp) do
    if (Macro.expand_once(a, __ENV__)), do: exp
  end
end

defmodule Foo do
  @flag true

  require M
  def main do
    M.ifa (@flag), do: IO.puts 123
  end
end

Foo.main
编译器会抱怨该属性

% /tmp/elixir-1.3.0-rc1/bin/elixir foobar.exs
** (ArgumentError) could not call get_attribute on module M because it was already compiled
    (elixir) lib/module.ex:1144: Module.assert_not_compiled!/2
    (elixir) lib/module.ex:1066: Module.get_attribute/3
    (elixir) lib/kernel.ex:2360: Kernel.do_at/4
    (elixir) expanding macro: Kernel.@/1
    foobar.exs:12: M.ifa/2
    expanding macro: M.ifa/2
    foobar.exs:12: Foo.main/0


% /tmp/elixir-1.2.6/bin/elixir foobar.exs
123
我想知道为什么在扩展宏之前编译Foo。
1.3中有什么变化?

Elixir实际上在您的代码中发现了一个bug!:D

在宏中,当您使用
\uuuuu ENV\uuuu
时,您是在定义宏的模块的上下文中扩展用户引用的表达式,而不是在调用方的上下文中。解决方案是在Elixir v1.2和v1.3中使用
\uuuuu调用者
来确保
@flag
得到正确的扩展:

defmodule M do
  defmacro ifa(a, exp) do
    if (Macro.expand_once(a, __CALLER__)), do: exp
  end
end

感谢您试用Elixir v1.3-rc

Elixir实际上在您的代码中发现了一个bug!:D

在宏中,当您使用
\uuuuu ENV\uuuu
时,您是在定义宏的模块的上下文中扩展用户引用的表达式,而不是在调用方的上下文中。解决方案是在Elixir v1.2和v1.3中使用
\uuuuu调用者
来确保
@flag
得到正确的扩展:

defmodule M do
  defmacro ifa(a, exp) do
    if (Macro.expand_once(a, __CALLER__)), do: exp
  end
end

感谢您试用Elixir v1.3-rc

到目前为止,我可以在1.2.6和1.3分支上的最新提交中重现相同的行为。我建议你在IRC频道(freenode上的elixir lang)或谷歌官方群组上询问,如果你在这里没有得到答案。这可能是一个bug,因为它破坏了在1.2中运行良好的代码。我可以在1.2.6中重现相同的行为,并且在1.3分支上的最新提交到现在为止。我建议你在IRC频道(freenode上的elixir lang)或谷歌官方群组上询问,如果你在这里没有得到答案。这可能是一个bug,因为它破坏了在1.2中运行良好的代码。