How do you define constants in Elixir modules?

Solution 1:

You can prepend your variable name with @:

defmodule MyModule do
  @my_favorite_number 13
end

Here are the docs

Solution 2:

Another approach to defining constants is one that I took with the wxErlang header files. That is, you can simply define a single line function that returns the constant value for you. Like so:

  def wxHORIZONTAL, do: 4
  def wxVERTICAL, do: 8
  def wxBOTH, do: (wxHORIZONTAL ||| wxVERTICAL)

and here's another example from the same source code:

 # From "defs.h": wxDirection
  def wxLEFT, do: 16
  def wxRIGHT, do: 32
  def wxUP, do: 64
  def wxDOWN, do: 128
  def wxTOP, do: wxUP
  def wxBOTTOM, do: wxDOWN
  def wxNORTH, do: wxUP
  def wxSOUTH, do: wxDOWN
  def wxWEST, do: wxLEFT
  def wxEAST, do: wxRIGHT
  def wxALL, do: (wxUP ||| wxDOWN ||| wxRIGHT ||| wxLEFT)

As you can see it makes it a little easier to define a constant in terms of another constant. And when I want those constants in a different module all I need to do is to require WxConstants at the top of the module. This makes it much easier to define a constant in one place and use it in several others--helps a lot with DRY.

By the way, you can see the repo here if you're curious.

As I say, I add this answer mostly for sake of completeness.

Solution 3:

Looking around github I see this being used which appeals to me. Allows the constant to be accessed from other modules.

ModuleA
  @my_constant 23

  defmacro my_constant, do: @my_constant


ModuleB
  Require ModuleA
  @my_constant ModuleA.my_constant

Yet again simple and facinating elixir solution

Solution 4:

Maybe you define a constants module file and in it you can define macros for this like so

defmodule MyApp.Constants do
  defmacro const_a do
    quote do: "A"
  end
end

You use it by importing it into any other module

defmodule MyApp.ModuleA do
  import MyApp.Constants

  def get_const_a do
    const_a()
  end 
end

The benefit is also that you don't incur any runtime cost as well as the advantage of using it in case matches

case something do
  const_a() -> do_something
  _ -> do_something_else
end

Solution 5:

Elixir modules can have associated metadata. Each item in the metadata is called an attribute and is accessed by its name. You define it inside a module using @name value. And is accessed as @name

defmodule Example
  @site 'StackOverflow' #defining attribute

  def get_site do
    @site #access attribute
  end 
end

Remeber this works only on top level of a module and you cannot set a module attribute inside a function definition.