【发布时间】:2015-02-03 05:18:30
【问题描述】:
Ruby 有开放类,非常方便(尽管被一些人斥责),并且 Elixir 从 Ruby 中大量借鉴,所以我希望 Elixir 允许我在关闭模块后重新打开模块并添加宏,但这确实不能以我尝试的方式工作。有没有办法做到这一点? Elixir 中是否提供此功能?
为了具体说明,让我们以 Chris McCord 的 Metaprogramming Elixir 为例:
defmodule Math do
defmacro say({:+, _, [lhs, rhs]}) do
quote do
lhs = unquote(lhs)
rhs = unquote(rhs)
result = lhs + rhs
IO.puts "#{lhs} plus #{rhs} is #{result}"
result
end
end
defmacro say({:*, _, [lhs, rhs]}) do
quote do
lhs = unquote(lhs)
rhs = unquote(rhs)
result = lhs * rhs
IO.puts "#{lhs} times #{rhs} is #{result}"
result
end
end
end
如果我再添加一个减法宏
defmodule Math do
defmacro say({:-, _, [lhs, rhs]}) do
quote do
lhs = unquote(lhs)
rhs = unquote(rhs)
result = lhs - rhs
IO.puts "#{lhs} minus #{rhs} is #{result}"
result
end
end
end
我收到一条警告,提示我正在重新定义模块 Math,并且最初定义的宏失败。所以很明显我的方法不是正确的,但是还有另一种方法可以实现同样的目标吗?
【问题讨论】:
-
您不应将类的概念与模块混淆。虽然它们有一些相似之处,但它们远非同一件事。例如,Elixir 模块中没有私有数据之类的东西。
-
顺便说一下,您的示例并没有真正使用宏功能。建议您尽可能坚持使用功能,这可以在这里轻松完成。只需使用
def而不是defmacro并删除所有quotes 和unquotes。 -
是的,没错,但我希望您意识到这不是 my 的示例,而是 Chris McCord 的示例,它只是用于演示目的的“琐碎”示例。不过你的观点是正确的。
标签: elixir