简体   繁体   English

Elixir引用/取消引用和宏行为

[英]Elixir quote/unquote and macros behaviour

I have two versions of __using__ , however, first version has different behaviour from one I've expected. 我有__using__两个版本,但是,第一个版本的行为与我预期的不同。 This code does not work properly (actually, it does not import anything). 此代码无法正常工作(实际上,它不会导入任何内容)。

defmodule SomeModule do
  defmacro __using__(opts \\ []) do
    quote do
      opts = unquote(opts)
      if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do
        import MyModuleOne
      else
        import MyModuleTwo
      end
    end
  end
end

And this is the working version, however, I don't like having two separate quote parts. 这是工作版本,但是,我不喜欢有两个单独的quote部分。

defmodule SomeModule do
  defmacro __using__(opts \\ []) do
    if Keyword.has_key?(opts, :my_key) && opts[:my_key] == 3 do
      quote do
        import MyModuleOne
      end
    else
      quote do
        import MyModuleTwo
      end
    end
  end
end

How should the first one be rewritten for it to work properly? 应该如何重写第一个以使其正常工作?

That's a tricky one! 那是一个棘手的问题! Took me a while to work out the reason... 花了我一段时间找出原因...

Before going into why, let me assure you that your macro is perfectly valid, and Elixir works precisely as you told it . 在深入探讨原因之前,让我向您保证您的宏完全有效,并且Elixir的工作原理与您所说的完全一样

I tried to expand the two macros you posted and got the same result, ie the correct thing is being imported. 我试图扩展您发布的两个宏,并得到相同的结果,即正在导入正确的东西。 But why does it not work as you expected? 但是,为什么它不按预期工作?

Here is why, 这就是为什么

It is important to notice that import/2 is lexical 重要的是要注意import / 2是词法的

from the docs for import 从文档import

and let me show you 2 examples 让我给你看两个例子

iex(1)> import Enum, only: [into: 2]
Enum
iex(2)> into [a: 1], %{}
%{a: 1}
iex(3)>

and... 和...

iex(1)> if true do
...(1)>   import Enum, only: [into: 2]
...(1)> end
Enum
iex(2)> into [a: 1], %{}
** (CompileError) iex:2: undefined function into/2

the import only takes effect inside the clause that you wrote it :) 导入仅在您编写的子句中生效:)

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

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