如何与Elixir共享模块之间的常量(原子列表)?

时间:2016-06-02 11:16:31

标签: elixir

作为一个完整的Elixir新手,我尝试过这样的事情:

defmodule ConstantDoodleElixir do
    @constants [:con1, :con2]

    def constants, do: @constants

end

defmodule ConstantReceiver do

    def receive_constant(constant) when constant in ConstantDoodleElixir.constants do
        constant
    end
end

这当然不起作用,因为现在列表在编译时不可用。那么,如果我想将一个常量列表从一个模块共享到另一个模块,那么最佳实践是什么?

在此先感谢,所有答案都非常感谢。

1 个答案:

答案 0 :(得分:3)

正如您所确定的那样,在编译时函数不可用。但是,宏在编译时可用,因此您可以执行以下操作:

defmodule ConstantDoodleElixir do
  @constants [:con1, :con2]

  defmacro constants, do: unquote(@constants)

end

defmodule ConstantReceiver do
  require ConstantDoodleElixir
  def receive_constant(constant) when constant in ConstantDoodleElixir.constants do
    constant
  end
end

ConstantReceiver.receive_constant(:con1)
ConstantReceiver.receive_constant(:con2)
ConstantReceiver.receive_constant(:con3) # will error

您不能使用不在守卫内部允许的功能子集中的功能。您可以使用编译为其中一个可接受函数的宏。 http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses

您还可以检查功能内部:

defmodule ConstantDoodleElixir do
  @constants [:con1, :con2]

  def constants, do: @constants

end

defmodule ConstantReceiver do
  def receive_constant(constant) do
    if constant in ConstantDoodleElixir.constants do
      constant
    else
      raise ArgumentError, message: "#{constant} not allowed"
    end
  end
end

ConstantReceiver.receive_constant(:con1)
ConstantReceiver.receive_constant(:con2)
ConstantReceiver.receive_constant(:con3)