所以我想说我有一个模块App.A
,它有以下代码
defmodule App.A do
defmacro __using__(_) do
quote do
alias App.B
end
end
end
所以当它为used
时,会自动为App.B
添加别名。
现在,还有一个名为App.C
的模块定义如下:
defmodule App.C do
defmacro __using__(_) do
quote do
use App.A
def foo do
B.bar()
end
end
end
end
添加了一个函数foo
,它试图在没有显式调用模块B
的情况下调用函数
别名,因为我希望使用App.A
已经定义了一个别名。
现在问题是,当我有其他模块时,请说App.D
uses
App.C
,
编译会给我一个警告,说B是未定义的,因此别名不起作用。
有人可以解释为什么会发生这种情况吗?
答案 0 :(得分:2)
别名是使用它们的范围的本地。 quote
宏的__using__
块在调用模块的函数中执行,因此别名有效。但是,当调用use App.C
时 - 别名不在该范围内,因此调用B.bar()将失败。
您可以将App.C
更改为:
defmodule App.C do
defmacro __using__(_) do
quote do
use App.A
IO.inspect B == App.B # false
alias App.B
IO.inspect B == App.B # true
def foo do
B.bar()
end
end
end
end
你会注意到只要c.ex中存在别名,它就会起作用。您可以在使用它之前在文件中的任何位置定义它:
alias App.B
defmodule App.C do
# alias App.B
defmacro __using__(_) do
# alias App.B
quote do
use App.A
# alias App.B
def foo do
# alias App.B
B.bar()
end
end
end
end