Sometimes it’s really useful, or let’s say even necessary, to configure your function-level default values per environment.
Now, without any further ado, here is how you do it:
@default_tty 1000 * 60
def something(ttl \\ default_ttl()) do
# do something
end
# Time to live (ttl) period (in milliseconds).
defp default_ttl do
Application.get_env(:myapp, :some_topic, @default_ttl)
end
This means that it might be useful to configure different values for the test
, dev
, and production
environments but it wouldn’t work on a runtime level or per instance. This is just the way Elixir as a compiled language works. When the code is compiled, it needs to know what the function would use as default values for optional arguments.
Be careful in dependency scenarios
As you can read in this old issue back from 2015 there is a non-obvious behavior related to this coding option. When your code is used as a dependency in another project. It’s the compile time of that dependency that is relevant and used for setting the default value then.
So be sure to run mix deps.clean dependencyA
in order for the default value to pick up the current setting. dependencyA
in this example would be the dependency that is using the env var default value in it’s function.
Summary
Using this way to configure the default value for your functions when needed, provides you with a beautiful balance of great performance at runtime, while still having a level of customizability using your config files.
What are your opinions and experiences on this? Any comments, critiques and suggestions are highly welcome.