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


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>Yes, it’s super simple if you don’t need to add things at runtime.</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">defmodule Data do
  # load external data
  @data [
    %{id: 1, other_key: :a},
    %{id: 2, other_key: :b},
    %{id: 3, other_key: :c},
  ]


  for key &lt;- [:id, :other_key] do
    for row &lt;- @data do
      def unquote(:"by_#{key}")(unquote(row[key])) do
        unquote(Macro.escape(row))
      end
    end

    def unquote(:"by_#{key}")(_) do
      nil
    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="108320" data-batch-url="/posts/batch_likers">
                        2
                      </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/best-way-to-keep-read-only-table-in-memory/18750/22">Post #21</a>
	                </div>
	            </div>
              <div id="likers-container-108320" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108320"
                     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 #21"></div>
  </section>
</div>
    <div class="postbit" id="108321" data-post-id="108321">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Cruz" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Cruz/120/13700_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Cruz
                    <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>and if I want to get the value of any key, Do I do value = Data.“by_#{key}”?</p>
<p>Sorry, I’m really struggling with macros</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108321" 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/best-way-to-keep-read-only-table-in-memory/18750/23">Post #22</a>
	                </div>
	            </div>
              <div id="likers-container-108321" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108321"
                     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 #22"></div>
  </section>
</div>
    <div class="postbit" id="108322" data-post-id="108322">
  <section>
    <div class="post-wrap">


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

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>In this example, you do <code>Data.by_id(1)</code> or <code>Data.by_other_key(:a)</code>.</p>
<p>Or if you want a unified api, you can put the key in argument as well:</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">def by(unquote(key), unquote(row[key])) do
</code></pre>
<p>Then call it like <code>Data.by(:id, 1)</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="108322" 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/best-way-to-keep-read-only-table-in-memory/18750/24">Post #23</a>
	                </div>
	            </div>
              <div id="likers-container-108322" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108322"
                     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 #23"></div>
  </section>
</div>
    <div class="postbit" id="108323" data-post-id="108323">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Cruz" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Cruz/120/13700_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Cruz
                    <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>Got it. Thank you</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108323" 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/best-way-to-keep-read-only-table-in-memory/18750/25">Post #24</a>
	                </div>
	            </div>
              <div id="likers-container-108323" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108323"
                     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 #24"></div>
  </section>
</div>
    <div class="postbit" id="108328" data-post-id="108328">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Cruz" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Cruz/120/13700_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Cruz
                    <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>OK. I hit an issue. I have the data in a CSV file, and to load it, I’m doing this:</p>
<pre><code>  def csv_to_map do
    "../test0.csv"
    |&gt; Path.expand(__DIR__)
    |&gt; File.stream!()
    |&gt; CSV.decode(headers: true)
    |&gt; Enum.to_list()
  end
</code></pre>
<p>That works fine, but if now I save it to a variable instead of the attribute you use, I get an error:</p>
<pre><code>data = csv_to_map

for key &lt;- [:id, :other_key] do
  for row &lt;- data do
    def unquote(:"by_#{key}")(unquote(row[key])) do
      unquote(Macro.escape(row))
    end
 end
</code></pre>
<p>== Compilation error in file lib/catalog.ex ==<br>
** (CompileError) lib/catalog.ex:15: undefined function key/0<br>
(elixir) src/elixir_bitstring.erl:142: :elixir_bitstring.expand_expr/4<br>
(elixir) src/elixir_bitstring.erl:27: :elixir_bitstring.expand/7<br>
(elixir) src/elixir_bitstring.erl:20: :elixir_bitstring.expand/4<br>
(stdlib) lists.erl:1354: :lists.mapfoldl/3<br>
(elixir) expanding macro: Kernel.def/2</p>
<p>That key variable is defined in the outer for comprehension, so I don’t understand why switching from an attribute to a variable makes a difference.</p>
<p>Thanks for your help</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108328" 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/best-way-to-keep-read-only-table-in-memory/18750/26">Post #25</a>
	                </div>
	            </div>
              <div id="likers-container-108328" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108328"
                     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 #25"></div>
  </section>
</div>
    <div class="postbit" id="108383" data-post-id="108383">
  <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 quote-modified" data-username="Cruz" data-post="26" data-topic="18750">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cruz/48/13700_2.png" class="avatar"> Cruz:</div>
<blockquote>
<p>data = csv_to_map for key &lt;- [:id, :other_key] do for row &lt;- data do def unquote(:“by_#{key}”)(unquote(row[key])) do unquote(Macro.escape(row)) end end</p>
</blockquote>
</aside>
<p>Try this (I know embedded for’s sometimes have issues I’ve seen so it’s best to combine them regardless, like this):</p>
<pre data-code-wrap="elixir"><code class="lang-elixir">data = csv_to_map

for key &lt;- [:id, :other_key], row &lt;- data do
  def unquote(:"by_#{key}")(unquote(row[key])) do
    unquote(Macro.escape(row))
 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="108383" 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/best-way-to-keep-read-only-table-in-memory/18750/27">Post #26</a>
	                </div>
	            </div>
              <div id="likers-container-108383" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108383"
                     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 #26"></div>
  </section>
</div>
    <div class="postbit" id="108391" data-post-id="108391">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Cruz" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Cruz/120/13700_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Cruz
                    <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>Thank you, but I still get the same error. The compiler doesn’t see “key” as being defined and expands it as a function. This is the code I have now:</p>
<pre><code>defmodule Catalog do
  def csv_to_map do
    "../test0.csv"
    |&gt; Path.expand(__DIR__)
    |&gt; File.stream!()
    |&gt; CSV.decode(strip_fileds: true, headers: true)
    |&gt; Enum.to_list()

  end

  def map_list_to_mem do
    data = csv_to_map()

    for key &lt;- [:id, :other_key], row &lt;- data do
      def unquote(:"by_#{key}")(unquote(row[key])) do
        unquote(Macro.escape(row))
      end

      def unquote(:"by_#{key}")(_) do
        nil
      end
    end
  end
end
</code></pre>
<p>And, I still get:<br>
== Compilation error in file lib/catalog.ex ==<br>
** (CompileError) lib/catalog.ex:15: undefined function key/0<br>
(elixir) src/elixir_bitstring.erl:142: :elixir_bitstring.expand_expr/4<br>
(elixir) src/elixir_bitstring.erl:27: :elixir_bitstring.expand/7<br>
(elixir) src/elixir_bitstring.erl:20: :elixir_bitstring.expand/4<br>
(stdlib) lists.erl:1354: :lists.mapfoldl/3<br>
(elixir) expanding macro: Kernel.def/2</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108391" 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/best-way-to-keep-read-only-table-in-memory/18750/28">Post #27</a>
	                </div>
	            </div>
              <div id="likers-container-108391" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108391"
                     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 #27"></div>
  </section>
</div>
    <div class="postbit" id="108402" data-post-id="108402">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="benwilson512" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/benwilson512/120/1457_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  benwilson512
                  </h3>
		          </div>
						
			          <div class="user-title">
									<span>Author of Craft GraphQL APIs in Elixir with Absinthe</span>
			          </div>
						</div>
					
					</div>

	        <div class="thread-main">
	            <div class="post-body" data-turbo="false">
								<p>The contents here need to happen in the module body if you’re trying to generate functions. This will all happen at compile time. If compile time isn’t when you want to do this then you’ll want to pick one of the other strategies.</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108402" 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/best-way-to-keep-read-only-table-in-memory/18750/29">Post #28</a>
	                </div>
	            </div>
              <div id="likers-container-108402" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108402"
                     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 #28"></div>
  </section>
</div>
    <div class="postbit" id="108405" data-post-id="108405">
  <section>
    <div class="post-wrap">


					<div class="post-header">
		        <div class="user-avatar">
		          <img alt="Cruz" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/Cruz/120/13700_2.png" width="120" height="120" />
		        </div>
					
						<div class="user-details">
		          <div class="user-name">
		            <h3>
                  Cruz
                    <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>I see. Beginners mistake <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">  I don’t know why I didn’t try that before.</p>
<p>BTW,   I was able to do the ETS based solution, and it’s working fine. I decided not to bother with Mnesia as I just have one additional index and I don’t think I’ll gain anything else from it.</p>
<p>But I’d like to finish at least one of the macro based solutions. Even if I don’t use it, I’m learning a lot.</p>
<p>Thanks a lot</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108405" 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/best-way-to-keep-read-only-table-in-memory/18750/30">Post #29</a>
	                </div>
	            </div>
              <div id="likers-container-108405" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108405"
                     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 #29"></div>
  </section>
</div>
    <div class="postbit" id="108410" data-post-id="108410">
  <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="Cruz" data-post="28" data-topic="18750">
<div class="title">
<div class="quote-controls"></div>
<img alt="" width="24" height="24" src="https://forum.elixirforum.com/user_avatar/forum.elixirforum.com/cruz/48/13700_2.png" class="avatar"> Cruz:</div>
<blockquote>
<p>Thank you, but I still get the same error. The compiler doesn’t see “key” as being defined and expands it as a function. This is the code I have now:</p>
</blockquote>
</aside>
<p>That’s not the code you gave before, earlier it was top level and it works (I tested), what you gave has the expansion happening inside another function call, which will most definitely fail, it needs to be at top level (like in the module definition itself).</p> 
	            </div>

	            <div class="base-line">
	                <div class="thread-counters">
	                    <span class="thread-count count-likes js-likers-trigger" title="Likes" data-post-id="108410" 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/best-way-to-keep-read-only-table-in-memory/18750/31">Post #30</a>
	                </div>
	            </div>
              <div id="likers-container-108410" 
                   class="likers-container"
                   data-first-post="false"
                   data-batch-url="/posts/batch_likers">
                   <div class="likers-placeholder" 
                     data-likers-post-id="108410"
                     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 #30"></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/18750/load_more?page=4">Load more posts (2 remaining)</a>
</div></template></turbo-stream>