[英]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.