How to reduce repetition in a config file?

Hey there - I am working with an elixir app where some of our business logic is defined in a config file. However, as time has gone on, we have noticed a lot of repetition in this file. That leads me to ask two questions. Take the following as an example snippet of what our config is like:

config :candy_app, :candy_flavors,
  default: [a: 1, b: 1, c:1],
  fruity: [a: 1, b: 1],
  chocolate: [a: 1, b: 1, c:1, d:1],
  vanilla: [a: 1, b: 1, c:1, d:1],
  caramel: [a: 1, b: 1, c:1, d:1],
  1. Is there a way to define a constant for a given value within the config file and then just reference that constant? Something like the following (although it doesn’t appear that @ will work since the config is defined outside of a module and you cannot invoke @/1 outside a module):
@default_flavors [a: 1, b: 1, c:1]
config :candy_app, :candy_flavors,
  default: @default_flavors,
  fruity: @default_flavors -- [c:1],
  chocolate: @default_flavors ++ [d:1],
  vanilla: @default_flavors ++ [d:1],
  caramel: @default_flavors ++ [d:1],
  1. Is there a way to define the same value for multiple keys in a keyword list without re-writing out that value multiple times? This would save a lot of space, especially since our real world config values are much longer than those in the example. I’m thinking something like this (although this doesn’t appear to work):
config :candy_app, :candy_flavors,
  default: [a: 1, b: 1, c:1],
  fruity: [a: 1, b: 1],
  chocolate:
  vanilla:
  caramel: 
    [a: 1, b: 1, c:1, d:1]

Is there any way to achieve what I am trying to do here? Any tips on approaches to take other than the two I listed above? I’d sure appreciate it! Thanks in advance.

Isn’t a regular variable working in the config file?
Or am I missing something here :thinking:

2 Likes

Oh wow. I’ll spare the reasons why I thought I had tried that and found that it didn’t work. But after your suggestion I tried the equivalent of this:

default_flavors = [a: 1, b: 1, c:1]
config :candy_app, :candy_flavors,
  default: default_flavors,
  fruity: default_flavors -- [c:1],
  chocolate: default_flavors ++ [d:1],
  vanilla: default_flavors ++ [d:1],
  caramel: default_flavors ++ [d:1],

And that does indeed appear to work. Despite the temptation to remove it, I’ll leave my question up in case someone else makes the same foolish mistake in the future :sweat_smile:

If you really want to remove items from the keyword list, maybe consider using Keyword.delete/2 or Keyword.drop/2 otherwise you have to change your config in 2 places when the value of :c changes.

2 Likes