<turbo-stream action="append" target="posts_list"><template>    <div class="postbit" id="18326" data-post-id="18326">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="michalmuskala" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/michalmuskala/120/20288_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  michalmuskala
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>When using an external file like that, consider adding <code>@external_resource path</code> to the module - it will tell the elixir compiler to recompile the module if the file changes.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="18326" data-batch-url="/posts/batch_likers">
                        4
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/12">Post #11</a>
	                </div>
	            </div>
              <div id="likers-container-18326" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="18326"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #11"></div>
  </section>
</div>
    <div class="postbit" id="18332" data-post-id="18332">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="sasajuric" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/sasajuric/120/991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  sasajuric
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Elixir In Action</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="benperiton" data-post="11" data-topic="2799">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benperiton/48/1572_2.png" class="avatar"> benperiton:</div>
<blockquote>
<p>I was thinking of prepending the name of the file to each key in the JSON file to help namespace it a bit</p>
</blockquote>
</aside>
<p>You could also reach for multiple “nested” modules. Basically, for each input json file name, create the module alias using <code>Module.concat</code>, and then define the module dynamically. That way you could invoke say <code>Const.System.decode/encode</code>, assuming the input file is <code>system.json</code>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="18332" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/13">Post #12</a>
	                </div>
	            </div>
              <div id="likers-container-18332" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="18332"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #12"></div>
  </section>
</div>
    <div class="postbit" id="18339" data-post-id="18339">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benperiton" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benperiton/120/1572_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benperiton
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Thanks guys, I’m really liking where this has gone! So, I’ve tried to implement both of those ideas, and I now have</p>
<pre><code>defmodule API.Const do
  @root_dir       File.cwd!
  @const_dir      Path.join(~w(#{@root_dir} lib imsapi common constants))
  @const_files    Path.wildcard("#{@const_dir}/**/*.json")

  for filename &lt;- @const_files do
    # Watch for changes and recompile
    @external_resource filename

    # This will be the new module: API.Const.&lt;group&gt;
    group = filename
            |&gt; Path.basename(".json")
            |&gt; String.capitalize

    file_consts = File.read!(filename)
                  |&gt; Poison.decode!

    defmodule Module.concat([API, Const, group]) do
      for {key, value} &lt;- file_consts do
        def encode(unquote(String.to_atom(key))),   do: unquote(value)
        def decode(unquote(value)), do: unquote(String.to_atom(key))
      end
    end
  end
end
</code></pre>
<p>That makes a much nicer way to access the different files, so thanks for that suggestion <a class="mention" href="/u/sasajuric" rel="nofollow">@sasajuric</a>! I’m not sure if I’m doing something wrong, but it doesn’t seem to recompile if I modify one of the JSON files?</p>
<p>I’m running it using <code>iex -S mix phoenix.server</code></p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="18339" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/14">Post #13</a>
	                </div>
	            </div>
              <div id="likers-container-18339" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="18339"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #13"></div>
  </section>
</div>
    <div class="postbit" id="18360" data-post-id="18360">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benperiton" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benperiton/120/1572_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benperiton
                    <span class="op-star" title="Thread Starter">
                      <img alt="OP" class="op-star-icon" src="/assets/thread-icons/thread-icon-thread-starter-df91e872.png" />
                    </span>
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Seems I’ve been spending too much time using things that live reload code, the files DO recompile if I change the JSON, I was just waiting for it to happen live <img src="https://forum.elixirforum.com/images/emoji/apple/blush.png?v=15" title=":blush:" class="emoji" alt=":blush:" loading="lazy" width="20" height="20"></p>
<p>I’m sure there are things I can tweak in the below, but it seems to work fine for what I need right now.</p>
<ul>
<li>Split over multiple JSON files</li>
<li>Custom Ecto field for converting when entering/retrieving from DB</li>
<li>Allow atoms to be used during dev/debug, but integers for storage/comms</li>
<li>Re-compiles when any JSON file changes</li>
<li>Dynamically create “nested modules” based on the JSON filename</li>
</ul>
<p>So this is end result of all the suggestions (thanks again!)</p>
<pre><code>defmodule API.Const do
  @moduledoc """
  A single point that we can use constants from. Rather than using something
  like a map to expose atoms =&gt; integers we create a set of functions that 
  let us encode/decode from either atom =&gt; integer or integer =&gt; atom. Doing this
  makes it a lot easier to debug things as we are basically just using atoms 
  everywhere in the code - we change to integers on the app boundary.

  We still break up the constants with regards to their respective areas, and 
  then we just include everything in here. We store the constatnts as JSON files
  so that we can export into frontend clients if needed,

  Discussion here: https://forum.elixirforum.com/t/shared-module-constants/2799/
  
  Eg:

  API.Const.System.encode(:ORG_STATUS_ACTIVE) =&gt; 100101
  API.Const.System.decode(100101) =&gt; :ORG_STATUS_ACTIVE
  """

  @root_dir       File.cwd!
  @const_dir      Path.join(~w(#{@root_dir} lib imsapi common constants))
  @const_files    Path.wildcard("#{@const_dir}/**/*.json")

  for filename &lt;- @const_files do
    # Watch for changes and recompile
    @external_resource filename

    # This will be the new module: API.Const.&lt;group&gt;
    group = filename
            |&gt; Path.basename(".json")
            |&gt; String.capitalize

    file_consts = File.read!(filename)
                  |&gt; Poison.decode!

    
    # Creates a module under the main API.Const module using the filename.
    # 
    # Eg a system.json file would end up as `API.Const.System`
    defmodule Module.concat([API, Const, group]) do
      for {key, value} &lt;- file_consts do
        def encode(unquote(String.to_atom(key))),   do: unquote(value)
        def decode(unquote(value)), do: unquote(String.to_atom(key))
      end

      # Creates a new module that can be used with Ecto models to hsve s field
      # that is automatically encoded/decoded as data is retrieved/entered.
      # Name is the same as the outer module, with `Ecto` appended
      # 
      # Eg a system.json file would end up as `API.Const.System.EctoField`
      defmodule Module.concat([API, Const, group, EctoField]) do
        @behaviour Ecto.Type

        @group_mod Module.concat([API, Const, group])

        def type, do: :integer

        def cast(int) when is_integer(int), do: {:ok, apply(@group_mod, :decode, [int])}
        def cast(atom) when is_atom(atom), do: {:ok, atom}
        def cast(_), do: :error

        def load(int) when is_integer(int), do: {:ok, apply(@group_mod, :decode, [int])}
        def load(_), do: :error

        def dump(atom) when is_atom(atom), do: {:ok, apply(@group_mod, :encode, [atom])}
        def dump(_), do: :error
      end
    end
  end
end
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="18360" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/15">Post #14</a>
	                </div>
	            </div>
              <div id="likers-container-18360" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="18360"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #14"></div>
  </section>
</div>
    <div class="postbit" id="102846" data-post-id="102846">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="thiagomajesk" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/120/31904_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  thiagomajesk
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Coming from a static language background it’s really hard to get around the “elixir-way”.</p>
<p><a class="mention" href="/u/overminddl1" rel="nofollow">@OvermindDL1</a> What would be your approach if instead of integers you’d need a list of atoms?<br>
Imagine if you needed to validate a list of valid countries; it seems a bit overkill (due to repetition) to just:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def countries, do: %{
united_states: :united_states,
canada: :canada,
paris: :paris,
england: :england
}

# maybe just... (???)
# def valid_countries, do: [:united_states, :canada, :paris, :england]
</code></pre>
<p>Instead of simply scattering atoms in the application, I like the idea to have a “single source of truth” to serve like self-documentation (mainly autocomplete). In that case, I’d typically use an enum or a class with static const properties in C#.</p>
<p><strong>PS.:</strong> BTW I don’t like very much the idea of using loose JSON files in the project like <a class="mention" href="/u/benperiton" rel="nofollow">@benperiton</a>.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="102846" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/16">Post #15</a>
	                </div>
	            </div>
              <div id="likers-container-102846" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="102846"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #15"></div>
  </section>
</div>
    <div class="postbit" id="102870" data-post-id="102870">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="OvermindDL1" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/OvermindDL1/120/2677_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  OvermindDL1
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="thiagomajesk" data-post="16" data-topic="2799">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/48/31904_2.png" class="avatar"> thiagomajesk:</div>
<blockquote>
<p>What would be your approach if instead of integers you’d need a list of atoms?</p>
</blockquote>
</aside>
<p>Just return a list of them then, no need to duplicate them.  <img src="https://forum.elixirforum.com/images/emoji/apple/slight_smile.png?v=15" title=":slight_smile:" class="emoji" alt=":slight_smile:" loading="lazy" width="20" height="20"></p>
<p>Making a map of them can still be quite useful because it allows for O(log N) lookup instead of O(N) if you just need to verify it is valid or not (I generally do the values as just <code>true</code> in that case because convention, but doesn’t really matter).</p>
<aside class="quote no-group" data-username="thiagomajesk" data-post="16" data-topic="2799">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/48/31904_2.png" class="avatar"> thiagomajesk:</div>
<blockquote>
<p>Instead of simply scattering atoms in the application, I like the idea to have a “single source of truth” to serve like self-documentation (mainly autocomplete). In that case, I’d typically use an enum or a class with static const properties in C#.</p>
</blockquote>
</aside>
<p>Likewise, and baking them into a module like this is the way to do that, the values all get interned into the system and no GC will touch them and their linked usage anywhere will not trigger GC either, it’s very efficient.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="102870" data-batch-url="/posts/batch_likers">
                        1
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/17">Post #16</a>
	                </div>
	            </div>
              <div id="likers-container-102870" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="102870"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #16"></div>
  </section>
</div>
    <div class="postbit" id="179316" data-post-id="179316">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="mrpola" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mrpola/120/19101_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  mrpola
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>I’m trying to achieve the same thing but with autocomplete functionality to know which atoms are available for use.<br>
Would there be any performance drawbacks if I create a function for each key value pair?<br>
I’m new to Elixir, sorry if this is a silly question</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule ErrorMessage do
  values = [
    account_not_found: "Error message for account not found" ,
    account_blocked: "Error message for account blocked" ,
    account_suspended: "Error message for account suspended",
    ...
  ]

  for {key, value} &lt;- values do
    def unquote(:"#{key}")(), do: unquote(value)
  end
end

</code></pre>
<p>And then, when I need to use the error message</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">alias ErrorMessage, as: E
assert response === E.account_not_found
</code></pre>
<p>This way the editor offers me all available functions in the module as autocomplete</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="179316" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/18">Post #17</a>
	                </div>
	            </div>
              <div id="likers-container-179316" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179316"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #17"></div>
  </section>
</div>
    <div class="postbit" id="179324" data-post-id="179324">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="thiagomajesk" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/thiagomajesk/120/31904_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  thiagomajesk
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<aside class="quote no-group" data-username="mrpola" data-post="18" data-topic="2799">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/mrpola/48/19101_2.png" class="avatar"> mrpola:</div>
<blockquote>
<p>I’m trying to achieve the same thing but with autocomplete functionality to know which atoms are available for use.</p>
</blockquote>
</aside>
<p>I recommend that you take a look at the <a href="https://github.com/gjaldon/ecto_enum" rel="noopener nofollow ugc">EctoEnum</a> library for insights.</p>
<p>It’s worth mentioning to people coming to this thread that after getting used to Elixir it feels more natural to pass atoms around, so that’s not a big deal. The minor drawback is refactoring; you’ll have to <em>find-all/ replace-all</em> instead of just hitting the refactor/ rename button in your editor (the outcome tends to be virtually the same).</p>
<p>In most cases, having good documentation on the available options is sufficient.<br>
Also, I think you shouldn’t worry too much about having autocomplete for that. Instead, you can write <a href="https://hexdocs.pm/elixir/writing-documentation.html" rel="noopener nofollow ugc">documentation</a> and <a href="https://hexdocs.pm/elixir/typespecs.html" rel="noopener nofollow ugc">typespecs</a> for your public APIs to achieve a similar goal.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="179324" data-batch-url="/posts/batch_likers">
                        3
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/19">Post #18</a>
	                </div>
	            </div>
              <div id="likers-container-179324" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="179324"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #18"></div>
  </section>
</div>
    <div class="postbit" id="299246" data-post-id="299246">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="apoorv-2204" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/apoorv-2204/120/25991_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  apoorv-2204
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Is it still valid today?</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="299246" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/20">Post #19</a>
	                </div>
	            </div>
              <div id="likers-container-299246" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="299246"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #19"></div>
  </section>
</div>
    <div class="postbit" id="299307" data-post-id="299307">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="ImNotAVirus" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/ImNotAVirus/120/14224_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  ImNotAVirus
                  </h3>
		          </div>
						
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yes it is.</p>
<p>Or you can use <a href="https://github.com/ImNotAVirus/simple_enum" rel="noopener nofollow ugc">simple_enum</a> (written by myself ^^) which does exactly the same thing with a few extra features.</p>
<p>Here is an example from the <a href="https://hexdocs.pm/simple_enum/overview.html" rel="noopener nofollow ugc">documentation</a>:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">iex&gt; defmodule MyEnums do
...&gt;   import SimpleEnum, only: [defenum: 2]
...&gt;
...&gt;   defenum :color, [:blue, :green, :red]
...&gt;   defenum :day, monday: "MON", tuesday: "TUE", wednesday: "WED"
...&gt; end

iex&gt; require MyEnums

iex&gt; MyEnums.color(:blue)
0
iex&gt; MyEnums.color(0)
:blue
iex&gt; MyEnums.day(:monday)
"MON"
iex&gt; MyEnums.day("MON")
:monday
</code></pre> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="299307" data-batch-url="/posts/batch_likers">
                        0
                      </span>
                      <!-- <span class="thread-count js-solved-indicator" title="Marked as solution"></span> -->
	                </div>
	                <div class="go-to-post">
	                  <a title="Go to post" alt="Go to post" href="https://forum.elixirforum.com/t/shared-module-constants/2799/21">Post #20</a>
	                </div>
	            </div>
              <div id="likers-container-299307" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="299307"
                     data-batch-url="/posts/batch_likers">
                  <div class="post-likers"></div>
                </div>
              </div>
	        </div>
			

    </div>

    <div class="triangle-top-right type-standard-post cat-standard-post" title="Post #20"></div>
  </section>
</div>
</template></turbo-stream><turbo-stream action="replace" target="load-more-container"><template><div id="load-more-container" class="load-more-container">
    <a class="load-more-button" data-turbo-stream="true" href="/topics/2799/load_more?page=3">Load more posts (1 remaining)</a>
</div></template></turbo-stream>