当前位置: 动力学知识库 > 问答 > 编程问答 >

How do I share constants (list of atoms) between modules with Elixir?

问题描述:

Being a total Elixir newbie I tried something like this:

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

This of course does not work because now the list is not available in compile time. So what is the best practice if I want to share list of constants from one module to another?

Thanks in advance, all answers much appreciated.

网友答案:

Functions are not available at compile time, as you have identified. However macros are available at compile time, so you can do something like:

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

You can't use functions that are not in the subset of functions allowed inside of guards. You can use macros that compile down to one of the accepted functions though. http://elixir-lang.org/getting-started/case-cond-and-if.html#expressions-in-guard-clauses

You can also check inside of the function:

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)
分享给朋友:
您可能感兴趣的文章:
随机阅读: