Reputation: 304
Can I define constant shared with modules?
Generally, we use module attribute for constant inside module. http://elixir-lang.github.io/getting-started/module-attributes.html#as-constants
If I want to make constant available to other modules, how can I do it? At first, module attribute is available just only inside module(1). I know I can use function as constant(2). But if possible, I want to define constant by dedicated form like 3.
defmodule Sample do
# 1. module attribute(available only inside module)
@private_const_value 1
# 2. function as constant(possible in any rate)
def const_value_func, do: 3
# 3. ideal form(but compile error)
public_const_value = 2
end
defmodule Client do
def foo() do
IO.puts "CONST = #{Sample.@private_const_value}" # compile error
IO.puts "CONST = #{Sample.const_value_func}"
IO.puts "CONST = #{Sample.public_const_value}" # compile error
end
end
I expect that constant satisfies following requirements.
Upvotes: 3
Views: 1914
Reputation: 1639
A non-module-specific constant is generally put in config/foo.exs
, and accessed by System.get_env/1
or Application.get_env/2
. If you want it to be under/inside a specific module (and not just a specific application) for reasons that can't be satisfied by just giving it an appropriate name and using one of the above options... first, be sure that that's accurate and you have a good reason, because I can't think of one off the top of my head.
If you still want that, the answer is (AFAIK) just your option-2, the function. If you want a dedicated form for it, do it with a macro:
defmacro const([{name, val}]) do
quote do
def unquote(name) do: unquote(val)
end
end
Then you can just do const foo: 87
in any module where you've required and imported the module with const
defined in it.
Or you could define each constant as a macro instead of a function. Disadvantage: You need to require
the modules. Advantage: Resolves at compile-time, like attributes do. Though functions of arity 0 that don't have side effects might do that anyway, I'm not sure but it's a reasonable optimization.
Upvotes: 5
Reputation: 15293
You also want to take a look at the Module.register_attribute function. You'd use this in conjunction with Module.get_attribute. I seem to recall something about using this as a means to share attributes across modules.
Upvotes: 0