<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>brainlid.org</title>
    <description>Mark Ericksen on the web. A blog of my thoughts, snippets, notes and discoveries.
</description>
    <link>http://brainlid.org/</link>
    <atom:link href="http://brainlid.org/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Wed, 01 Mar 2023 15:02:37 -0700</pubDate>
    <lastBuildDate>Wed, 01 Mar 2023 15:02:37 -0700</lastBuildDate>
    <generator>Jekyll v3.0.1</generator>
    
      <item>
        <title>Pattern Matching to Format Text</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/img/alex-block-yarn-750px.png&quot; alt=&quot;Yarn rolls&quot; /&gt;
Photo by Alex Block on Unsplash&lt;/p&gt;

&lt;p&gt;Using string pattern matching to format text? Sure!&lt;/p&gt;

&lt;p&gt;We store text like phone numbers, and Social Security Numbers (SSN) as unformatted text. When a user submits the data, we strip all formatting and non-number characters from it. If a user enters &lt;code class=&quot;highlighter-rouge&quot;&gt;800.555.4444&lt;/code&gt;, we store &lt;code class=&quot;highlighter-rouge&quot;&gt;8005554444&lt;/code&gt;. When it comes time to render the value into a PDF, document or export it in some other way, we format it in a consistent way like &lt;code class=&quot;highlighter-rouge&quot;&gt;(800) 555-4444&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Elixir (and the BEAM) supports &lt;a href=&quot;https://elixir-lang.org/getting-started/binaries-strings-and-char-lists.html&quot;&gt;pattern matching binary strings&lt;/a&gt;, making this very clean and fun.&lt;/p&gt;

&lt;p&gt;This is documented in &lt;a href=&quot;https://hexdocs.pm/elixir/Kernel.SpecialForms.html#%3C%3C%3E%3E/1&quot;&gt;Kernel.SpecialForms under «arg»&lt;/a&gt;. You can use this in very powerful ways like matching on web protocols, parsing PNGs and more. However, sometimes the straight-forward “string” uses are harder to find documented. I’m hoping to add to that here.&lt;/p&gt;

&lt;p&gt;The power is in the binary pattern match where I specify the length of each segment and bind it to a variable.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Format&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;three&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;four&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;three&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;four&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This example only matches a 7-character string.&lt;/p&gt;

&lt;p&gt;Here’s the full version that also supports formatting a 10-character value where an area-code is included.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Utils&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Format&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;@moduledoc&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;
  Functions for common string formatting.
  &quot;&quot;&quot;&lt;/span&gt;

  &lt;span class=&quot;nv&quot;&gt;@doc&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&quot;&quot;
  Format a phone number with an expected area code.

  ## Examples

      iex&amp;gt; Format.phone(&quot;8005554444&quot;)
      &quot;(800) 555-4444&quot;

      iex&amp;gt; Format.phone(&quot;5554444&quot;)
      &quot;555-4444&quot;

      iex&amp;gt; Format.phone(&quot;short&quot;)
      &quot;short&quot;

      iex&amp;gt; Format.phone(nil)
      nil

  &quot;&quot;&quot;&lt;/span&gt;
  &lt;span class=&quot;nv&quot;&gt;@spec&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;())&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;::&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;String&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;three&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;four&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;area&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;) &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;three&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;four&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;three&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;four&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;binary&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;size&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;three&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;four&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;phone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is_binary&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;),&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;other&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Why not make this a library? I find that usually &lt;em&gt;my application&lt;/em&gt; is pretty focused in what it needs. A public &lt;em&gt;library&lt;/em&gt; needs to support many different formats and different use-cases to be valuable.&lt;/p&gt;

&lt;p&gt;Elixir makes it so easy to do just what I need for my application that I don’t need to bring in a library or worry about creating one.&lt;/p&gt;

&lt;p&gt;I love Elixir. I solved a need in my application without a single &lt;code class=&quot;highlighter-rouge&quot;&gt;if&lt;/code&gt; conditional. It’s fully declarative, clear and performant.&lt;/p&gt;

&lt;p&gt;Where can you use binary pattern matching?&lt;/p&gt;
</description>
        <pubDate>Wed, 06 Mar 2019 05:00:00 -0700</pubDate>
        <link>http://brainlid.org/elixir/2019/03/06/pattern-match-format-text.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2019/03/06/pattern-match-format-text.html</guid>
        
        <category>elixir</category>
        
        <category>patterns</category>
        
        <category>matching</category>
        
        
        <category>elixir</category>
        
      </item>
    
      <item>
        <title>Git Aliases</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/img/unsplash-express-shortcut-750px.jpeg&quot; alt=&quot;Fist bumps&quot; /&gt;
Photo by &lt;a href=&quot;https://unsplash.com/photos/MzdoJwjayOs?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Dan Gold&lt;/a&gt; on &lt;a href=&quot;https://unsplash.com/?utm_source=unsplash&amp;amp;utm_medium=referral&amp;amp;utm_content=creditCopyText&quot;&gt;Unsplash&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://git-scm.com/&quot;&gt;Git&lt;/a&gt; is a version control tool used to track and manage
source code files and changes to those files. In sharing some of my development
tooling setup, I want to promote the use of &lt;a href=&quot;https://git-scm.com/docs/git-config#git-config-alias&quot;&gt;git
aliases&lt;/a&gt; as an “Express”
route or shortcut to commonly used commands.&lt;/p&gt;

&lt;p&gt;I don’t see enough people using them. People seem content to type out long
commands that they use on a regular basis.&lt;/p&gt;

&lt;p&gt;I just wanted to share a few of my favorite aliases here.&lt;/p&gt;

&lt;h2 id=&quot;my-favorite-aliases&quot;&gt;My Favorite Aliases&lt;/h2&gt;

&lt;p&gt;Git aliases are defined in the &lt;code class=&quot;highlighter-rouge&quot;&gt;.gitconfig&lt;/code&gt; file in your Home directory.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;[alias]
  b = branch
  r = remote -v
  s = status
  co = checkout
  uncommit = reset --soft HEAD^
  amend = commit --amend
  cp = cherry-pick -x&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;example-usage&quot;&gt;Example Usage&lt;/h2&gt;

&lt;p&gt;Instead of typing:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ git checkout master&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I can type:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ git co master&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Instead of:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ git status&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I only need to type:&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ git s&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When I accidentally commit changes to the wrong branch, it’s so easy to just
“uncommit” them.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ git uncommit&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; You should &lt;strong&gt;never&lt;/strong&gt; uncommit something that has already been pushed
to a remote.&lt;/p&gt;

&lt;p&gt;What git aliases are your favorites?&lt;/p&gt;
</description>
        <pubDate>Tue, 13 Nov 2018 05:00:00 -0700</pubDate>
        <link>http://brainlid.org/dev/2018/11/13/git-aliases.html</link>
        <guid isPermaLink="true">http://brainlid.org/dev/2018/11/13/git-aliases.html</guid>
        
        <category>git</category>
        
        
        <category>dev</category>
        
      </item>
    
      <item>
        <title>People are Processes</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/img/rawpixel-fist-bumps-750px.jpeg&quot; alt=&quot;Fist bumps&quot; /&gt;
Photo by rawpixel.com on Unsplash&lt;/p&gt;

&lt;p&gt;When designing your Elixir systems, think about the processes as people. Now
think of these people in an office all working together to serve the customer.
That is how you can build your software systems in Elixir. It’s natural and
intuitive!&lt;/p&gt;

&lt;h2 id=&quot;a-persons-state&quot;&gt;A Person’s State&lt;/h2&gt;

&lt;p&gt;A person’s mental “state” is like an Elixir process’ state.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;You know what you are thinking about.&lt;/li&gt;
  &lt;li&gt;You don’t know what someone else is thinking. It is private to them.&lt;/li&gt;
  &lt;li&gt;You can &lt;em&gt;ask&lt;/em&gt; that person what they are thinking.&lt;/li&gt;
  &lt;li&gt;That person can choose to reply and tell you what they are thinking.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;&lt;br /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018-01-17-processes-1-350px.png&quot; alt=&quot;Don&#39;t know current state&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018-01-17-processes-2-350px.png&quot; alt=&quot;Send message and ask&quot; /&gt;&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018-01-17-processes-3-350px.png&quot; alt=&quot;Reply with answer&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Elixir processes are very powerful. You might be tempted to think of a process
as a “thread” in traditional “multi-threaded” programming but that’s wrong and
will take you off course. “Threads” often &lt;em&gt;share state&lt;/em&gt; and two people can’t do
that. It’s unnatural and you end up resorting to things like mutexes to try and
keep things from breaking.&lt;/p&gt;

&lt;p&gt;Elixir’s processes provide a better way! And they are easier to think about too!&lt;/p&gt;

&lt;h2 id=&quot;your-software-system-is-like-an-office&quot;&gt;Your Software System is Like an Office&lt;/h2&gt;

&lt;p&gt;Your system is like an office. Let’s say the front door of your business
is a website and a request just came in. Who services that request? Are multiple
people involved in responding to that request?&lt;/p&gt;

&lt;p&gt;If you have a Ruby on Rails or PHP system, then your business probably looks
like a &lt;strong&gt;sole-proprietorship&lt;/strong&gt;. A single-person operation. An individual request
gets handled by a single process (or person). The business will do &lt;strong&gt;&lt;em&gt;nothing
else&lt;/em&gt;&lt;/strong&gt; until that one request is dealt with.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018-01-17-office-single-350px.png&quot; alt=&quot;Single person office&quot; /&gt;&lt;/p&gt;

&lt;p&gt;We get around this limitation by &lt;em&gt;cloning&lt;/em&gt; the whole business and hiding that
behind a facade to make it &lt;em&gt;look&lt;/em&gt; like one building. In tech terms, we run
multiple instances of the whole system behind load balancers but each instance
of the system can &lt;em&gt;only&lt;/em&gt; handle &lt;strong&gt;one request at a time&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018-01-17-office-cloned-350px.png&quot; alt=&quot;Single person office&quot; /&gt;&lt;/p&gt;

&lt;h2 id=&quot;elixir-and-phoenix-scale-your-business&quot;&gt;Elixir and Phoenix Scale Your Business!&lt;/h2&gt;

&lt;p&gt;When you build you business with Elixir and Phoenix, Phoenix takes care of
&lt;strong&gt;hiring&lt;/strong&gt; a new &lt;strong&gt;temp-worker&lt;/strong&gt; for every request. That temp-worker handles the
request and response. So, by just using Elixir and Phoenix, your system can
handle more load with fewer resources and responds to each request faster.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018-01-17-office-phoenix-350px.png&quot; alt=&quot;Temp Worker per Request&quot; /&gt;&lt;/p&gt;

&lt;p&gt;That’s awesome! Your business serves more customers and adds employees
on-demand and you don’t have to even think about it! You win!&lt;/p&gt;

&lt;p&gt;Now, do you think it could get &lt;em&gt;even better&lt;/em&gt;? Remember:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;processes are like people&lt;/li&gt;
  &lt;li&gt;your system is like an office&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Think of your system like an office. When you want to grow your business
beyond the &lt;strong&gt;sole-proprietor model&lt;/strong&gt;, how do you do that?&lt;/p&gt;

&lt;p&gt;You hire people! You assign people roles or positions and have them work
together to get more done! In fact, some of those people would be very
specialized like the sales-gal and the finance-guy.&lt;/p&gt;

&lt;p&gt;In tech terms, I create (hire) processes (people) and they send messages to each
other to coordinate and now more people are working at the same time! This is
how the real world works. This is how you work with other people. You understand
this instinctively. The novelty is realizing that &lt;strong&gt;you can have a software
system that works the same way&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2018-01-17-office-concurrent-350px.png&quot; alt=&quot;Concurrent Workers&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Now &lt;strong&gt;that&lt;/strong&gt; is a real business!&lt;/p&gt;

&lt;p&gt;The sole-proprietor model &lt;em&gt;is&lt;/em&gt; a bottle-neck. A small business will remain small
and unable to service more customers until they figure out how to scale and hire
more people. Don’t make that mistake with your software systems! Elixir has the
power to help you build a smarter business. That means you have a smarter
system.&lt;/p&gt;

&lt;h2 id=&quot;you-can-do-this-how&quot;&gt;You Can Do This! How?&lt;/h2&gt;

&lt;p&gt;Elixir can do this. &lt;strong&gt;You&lt;/strong&gt; can do this with Elixir! What do you do?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Think of your system like an office&lt;/li&gt;
  &lt;li&gt;Think of processes as the people in the office&lt;/li&gt;
  &lt;li&gt;How would you solve the problem with real people?&lt;/li&gt;
  &lt;li&gt;Hire more people!&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Use more processes! Concurrency for the win!&lt;/p&gt;

&lt;h2 id=&quot;want-to-move-faster&quot;&gt;Want to Move Faster?&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;mailto:&quot;&gt;Contact me&lt;/a&gt; to help your team and project
get to that point faster!&lt;/p&gt;

&lt;h2 id=&quot;want-more-detail&quot;&gt;Want More Detail?&lt;/h2&gt;

&lt;p&gt;Want to go deeper and get a better understanding? I presented on this topic and
more at an Elixir meetup. We make process and concurrency real!&lt;/p&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/UrIamY_ANDo?rel=0&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;
</description>
        <pubDate>Wed, 17 Jan 2018 10:00:00 -0700</pubDate>
        <link>http://brainlid.org/elixir/2018/01/17/people-are-processes.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2018/01/17/people-are-processes.html</guid>
        
        <category>elixir</category>
        
        <category>processes</category>
        
        <category>state</category>
        
        <category>video</category>
        
        
        <category>elixir</category>
        
      </item>
    
      <item>
        <title>Price&#39;s Law and Who&#39;s Doing the Work</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/img/jesse-orrico-184803-dirty-hands-750px.jpg&quot; alt=&quot;Doing the Work, dirty hands&quot; /&gt;
Photo by jesse orrico on Unsplash&lt;/p&gt;

&lt;h2 id=&quot;prices-law&quot;&gt;Price’s Law&lt;/h2&gt;

&lt;blockquote&gt;
  &lt;p&gt;The square root of the number of people in a domain do 50% of the work.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;This means that in a company of 10 employees, 3 of them do 1/2 the work. The remaining 50% of the work is done by the other 7 people.&lt;/p&gt;

&lt;p&gt;This scales too.&lt;/p&gt;

&lt;p&gt;When there are 100 employees, 10 of them do 1/2 the work. The other 90% are doing the other half of the work.&lt;/p&gt;

&lt;p&gt;As your company grows, incompetence grows exponentially and competence grows linearly.&lt;/p&gt;

&lt;p&gt;Price’s Law specifically applies to creative work. Meaning the creation of something “new” like new products, ideas, software, music compositions, basketball shots made, artwork, etc.&lt;/p&gt;

&lt;p&gt;The “Price” in Price’s Law is &lt;a href=&quot;https://en.wikipedia.org/wiki/Derek_J._de_Solla_Price&quot;&gt;Derek J. de Solla Price&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;practical-impacts&quot;&gt;Practical Impacts&lt;/h2&gt;

&lt;p&gt;I have seen this in my various workplaces. I also note  when company leadership doesn’t even know who their top performers are. They don’t know that these 3-4 people are doing 50% of the important creative work of the company.&lt;/p&gt;

&lt;p&gt;I have seen this law play out time and time again. I just didn’t know it was an actual law until recently. Now I am better able to pay attention and see it.&lt;/p&gt;

&lt;p&gt;Knowing this now, it becomes incredibly important to identify who the top performs are in our organizations. They are worth keeping and add incredible value. They may be fairly quiet too.&lt;/p&gt;

&lt;p&gt;I am a member of 3 different volunteer organizations, I work full time, and from time to time I have other creative efforts I works on outside of my other involvements.&lt;/p&gt;

&lt;p&gt;I recognize that in 1 volunteer group, I am “along for the ride” and am coasting. While in another, I am very involved, creating and leading.&lt;/p&gt;

&lt;p&gt;So the same person can occupy different creative positions and levels of involvement in their different social groups and at different times.&lt;/p&gt;

&lt;h2 id=&quot;short-video-of-lecture&quot;&gt;Short Video of Lecture&lt;/h2&gt;

&lt;iframe width=&quot;560&quot; height=&quot;315&quot; src=&quot;https://www.youtube.com/embed/UmUdcWk6Vfw?rel=0&amp;amp;start=16&quot; frameborder=&quot;0&quot; allowfullscreen=&quot;&quot;&gt;&lt;/iframe&gt;

&lt;p&gt;&lt;a href=&quot;https://www.youtube.com/watch?time_continue=16&amp;amp;v=UmUdcWk6Vfw&quot;&gt;Jordan Peterson on Price’s Law&lt;/a&gt; - A portion of his lecture where he explains it well.&lt;/p&gt;

&lt;h3 id=&quot;notes-from-lecture-video&quot;&gt;Notes from Lecture Video&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;10 employees, 3 of them do 1/2 the work&lt;/li&gt;
  &lt;li&gt;100 employees, 10 of them do 1/2 the work - that’s a problem, the other 90% are doing the other half.&lt;/li&gt;
  &lt;li&gt;10,000 employees 100 of them do 1/2 the work&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;As your company grows, incompetence grows exponentially and competence grows linearly.&lt;/p&gt;

&lt;p&gt;When a company has poor performance over a couple quarters, the 100 talented people who have options, leave. They are doing half the work. Another round of layoffs comes, the next set of top performers leaves. The company is now in a death spiral.&lt;/p&gt;

&lt;p&gt;This law applies in every single realm where there is creative production.&lt;/p&gt;

&lt;p&gt;Applies to city size, baskets scored, hockey goals scored.&lt;/p&gt;

&lt;p&gt;Compared to Monopoly game and the current 1% of rich people.  It is an inevitable conclusion of iterated trading games. We don’t know how to fight it.&lt;/p&gt;

&lt;p&gt;The top 1% end churns. It isn’t the same 1% all the time.&lt;/p&gt;

&lt;p&gt;In companies, people get stuck in their niche and don’t move. The redistribution of people after losing the top performers doesn’t get picked back up very well by the remaining people. The effect is attenuated.&lt;/p&gt;

&lt;p&gt;Companies can go into a death spiral that is almost impossible to get out of. Can happen extraordinarily quickly. Fortune 500 company’s churn. They only spend about 30 years at that level and value.&lt;/p&gt;

&lt;p&gt;Creative people are troublesome to work with. How do you evaluate a creative person? They are continually creating new things that are difficult to evaluate.&lt;/p&gt;
</description>
        <pubDate>Tue, 28 Nov 2017 11:20:45 -0700</pubDate>
        <link>http://brainlid.org/general/2017/11/28/price-law.html</link>
        <guid isPermaLink="true">http://brainlid.org/general/2017/11/28/price-law.html</guid>
        
        <category>creativity</category>
        
        <category>organizations</category>
        
        <category>video</category>
        
        
        <category>general</category>
        
      </item>
    
      <item>
        <title>Abusing Elixir Processes and State!</title>
        <description>&lt;p&gt;&lt;img src=&quot;/assets/img/joey-banks-380271-danger-750px.jpg&quot; alt=&quot;Danger! Photo by Joey Banks on Unsplash&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Recently I found a way of storing state in an Elixir Process that I hadn’t seen
before. I never read about it in a book, never saw it in a talk and haven’t seen
blog posts mentioning it. Did other people already know about this and it was
frowned on? Did others just &lt;strong&gt;not know about it&lt;/strong&gt;? But that couldn’t be, because
I found it being used internally in the Elixir Logger module!&lt;/p&gt;

&lt;p&gt;It’s called the &lt;strong&gt;“Process Dictionary”&lt;/strong&gt;.&lt;/p&gt;

&lt;p&gt;Before I dig in to the Dictionary and how easy it is to use and abuse, if you aren’t
already familiar with the recommended ways to manage state with processes, check
out &lt;a href=&quot;/elixir/2017/09/22/elixir-processes-and-state-recommended.html&quot;&gt;my earlier post&lt;/a&gt;
(or many others online).&lt;/p&gt;

&lt;p&gt;I setup a simple Github project that makes it easy to play with Elixir processes
and state management. &lt;a href=&quot;https://github.com/brainlid/meetup_process_state&quot;&gt;https://github.com/brainlid/meetup_process_state&lt;/a&gt;&lt;/p&gt;

&lt;h2 id=&quot;loggers-metadata&quot;&gt;Logger’s Metadata&lt;/h2&gt;

&lt;p&gt;&lt;a href=&quot;https://hexdocs.pm/logger/Logger.html&quot;&gt;Logger&lt;/a&gt; has a powerful feature of
tracking and including metadata on log entries. This is helpful for a Phoenix
application when you want to tie all related log entries together using a unique
request_id for the user’s request. In fact, Phoenix’s &lt;a href=&quot;https://github.com/elixir-plug/plug/blob/v1.4.3/lib/plug/request_id.ex&quot;&gt;Plug.RequestId module does
this&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;To see it in action, here is a simple example. Note that this is using &lt;a href=&quot;https://github.com/brainlid/meetup_process_state&quot;&gt;this
Github project&lt;/a&gt; which
configures Logger to output specified metadata.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;LoggerMeta&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;kn&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;setup_metadata&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;state_1:&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;always_here&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step_1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Step 1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step_2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Step 2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;step_3&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Step 3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;custom_1:&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;set_in_step_3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run_steps&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;setup_metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;step_1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;step_2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;step_3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Finished&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Given the code above, an IEx terminal session might look like this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;LoggerMeta&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run_steps&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;31.841&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.114&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;always_here&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Step&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;31.841&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.114&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;always_here&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Step&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;22&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;31.842&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.114&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;always_here&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;custom_1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;set_in_step_3&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Step&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Finished&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Did you notice that the “state_1=always_here” text in the log entry is on every
line? That message was set once in the &lt;code class=&quot;highlighter-rouge&quot;&gt;setup_metadata&lt;/code&gt; function with a call to
&lt;code class=&quot;highlighter-rouge&quot;&gt;Logger.metadata&lt;/code&gt;. Setting metadata on Logger this way is actually writing some
state to the process running the code. It is showing up with every step. In step
3 some custom log metadata is written out as well. However, this will only show
up for that one line.&lt;/p&gt;

&lt;p&gt;How is this accomplished? The running process isn’t a GenServer or using
tail-recursion to maintain state like the &lt;a href=&quot;/elixir/2017/09/22/elixir-processes-and-state-recommended.html&quot;&gt;recommended approaches&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Looking at the &lt;a href=&quot;https://github.com/elixir-lang/elixir/blob/v1.5.1/lib/logger/lib/logger.ex#L386&quot;&gt;Logger source&lt;/a&gt;,
we find this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keyword&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;c1&quot;&gt;# [...]&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nv&quot;&gt;@metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;enabled?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;metadata&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;process-dictionary&quot;&gt;Process Dictionary&lt;/h2&gt;

&lt;p&gt;An Elixir (and Erlang) process has a “Dictionary”. This is a local key-value
pair storage area. Local here means it is internal to the process.&lt;/p&gt;

&lt;p&gt;In Elixir, you can interface with it using these functions.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Process.html#delete/1&quot;&gt;Process.delete/1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Process.html#get/0&quot;&gt;Process.get/0&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Process.html#get/2&quot;&gt;Process.get/2&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Process.html#get_keys/0&quot;&gt;Process.get_keys/0&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Process.html#get_keys/1&quot;&gt;Process.get_keys/1&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Process.html#put/2&quot;&gt;Process.put/2&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The only function not exposed through Elixir is the “erase/0” function. Which
“erases the entire process dictionary. Returns the entire process diction before
it was erased.” So perhaps we can see why that isn’t being made conveniently
accessible.&lt;/p&gt;

&lt;p&gt;However, if you need to call it, you can do so this way…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;ss&quot;&gt;:erlang&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;erase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;a href=&quot;https://www.erlang.org/course/advanced#dict&quot;&gt;Erlang Advanced Course has this to say about the Process
Dictionary&lt;/a&gt;&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Each process has a &lt;em&gt;local&lt;/em&gt; store called the “Process Dictionary”.&lt;/p&gt;

  &lt;p&gt;[…]&lt;/p&gt;

  &lt;p&gt;Note that using the Process Dictionary:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Destroys referencial transparency&lt;/li&gt;
    &lt;li&gt;Makes debugging difficult&lt;/li&gt;
    &lt;li&gt;Survives Catch/Throw&lt;/li&gt;
  &lt;/ul&gt;

  &lt;p&gt;So:&lt;/p&gt;

  &lt;ul&gt;
    &lt;li&gt;Use with care&lt;/li&gt;
    &lt;li&gt;Do not over use - try the clean version first&lt;/li&gt;
  &lt;/ul&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now that we’ve introduced the Process Dictionary, lets abuse it!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;kn&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_1&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:greeting&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_2&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:count_to_10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state_3&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;run&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;ss&quot;&gt;:greeting&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello there!&quot;&lt;/span&gt;

      &lt;span class=&quot;ss&quot;&gt;:count_to_10&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;each&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;..&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;fn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;no&quot;&gt;IO&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;puts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;...&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
          &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sleep&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;500&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;ss&quot;&gt;:random&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;sayings&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Well, that&#39;s just great.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Sorry?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Eh?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Go on then!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;sayings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

      &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Try again!&quot;&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;In IEx we can interact with it like this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;      &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state_1&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;

      &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state_2&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;

      &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state_3&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;

      &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;other&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;We might see something like this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state_1&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello there!&quot;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state_2&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state_3&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Go on then!&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Sorry?&quot;&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Eh?&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Now imagine writing a unit test for the “run/0” function. It isn’t a “pure”
function. It isn’t obviously predictable. Imagine running across similar code in
a project. It takes more effort to understand it.&lt;/p&gt;

&lt;p&gt;What may not be immediately apparent above is that we are modifying the state of
the IEx process running our commands.&lt;/p&gt;

&lt;p&gt;So we can use &lt;code class=&quot;highlighter-rouge&quot;&gt;Process.get/1&lt;/code&gt; to examine the current &lt;code class=&quot;highlighter-rouge&quot;&gt;:state&lt;/code&gt; value we set in
the state_x functions from IEx and it can access the state.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:random&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Lets try changing it to something that isn’t supported by the code in the module.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;put&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;other&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:random&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;run&lt;/span&gt;
    &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Try again!&quot;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Using &lt;code class=&quot;highlighter-rouge&quot;&gt;Process.get/0&lt;/code&gt;, we can get the whole Process Dictionary returned to see
what it looks like.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;13&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Process&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;iex_history:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;IEx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;History&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;State&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;queue:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{[{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;Process.get(:state)\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;ss&quot;&gt;:random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.run\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Go on then!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.run\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Eh?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;9&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.run\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Eh?&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;8&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.state_3\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.run\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.state_2\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.run\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Hello there!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;DictionaryAbuse.state_1\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}],&lt;/span&gt;
       &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;&#39;alias ProcessState.DictionaryAbuse\n&#39;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
         &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;DictionaryAbuse&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]},&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;size:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;12&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;start:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
     &lt;span class=&quot;c1&quot;&gt;# [...],&lt;/span&gt;
     &lt;span class=&quot;ss&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:random&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
     &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;$ancestors&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;c1&quot;&gt;#PID&amp;lt;0.58.0&amp;gt;],&lt;/span&gt;
     &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;$initial_call&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;IEx&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Evaluator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:init&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}]&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;What’s this? The &lt;code class=&quot;highlighter-rouge&quot;&gt;IEx.Evaluator&lt;/code&gt; module that runs our commands in out beloved
IEx is storing the session’s command history in the Process Dictionary! It’s
even storing the results of the functions.&lt;/p&gt;

&lt;p&gt;Also we see that “$ancestors” and “$initial_call” are stored in every process.
The $ancestors is the owning process and $initial_call is what was used to start
this process.&lt;/p&gt;

&lt;p&gt;In fact, we can see the Process Dictionary in Observer when we view the IEx
process. There is a “Dictionary” tab.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;c1&quot;&gt;# which process is the IEx.Evaluator?&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#PID&amp;lt;0.114.0&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:observer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2017-09-24-iex_process_dictionary.png&quot; alt=&quot;observer inspecting IEx dictionary&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Curious! The Observer Dictionary page doesn’t include the &lt;code class=&quot;highlighter-rouge&quot;&gt;:iex_history&lt;/code&gt; that we
see when calling &lt;code class=&quot;highlighter-rouge&quot;&gt;Process.get/0&lt;/code&gt;. Mysteries remain!&lt;/p&gt;

&lt;p&gt;However, it’s time close out this long post looking at the Elixir/Erlang Process
Dictionary.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Logger and IEx both use the Process Dictionary. They both seem to be good and
appropriate uses. We should be aware of this tool so we can call on it when it
&lt;em&gt;is&lt;/em&gt; appropriate. I hope it is clear though that it can be easily abused making
code harder to test and reason about. If you abuse it, be prepared to take some
heat from your team.&lt;/p&gt;

&lt;p&gt;The goal here is to become aware of another, less talked about way of storing
state in a Process.&lt;/p&gt;

&lt;p&gt;For the final words, I’ll share what Fred Hebert, the author of &lt;a href=&quot;http://learnyousomeerlang.com/&quot;&gt;Learn You Some
Erlang for Great Good&lt;/a&gt; and &lt;a href=&quot;https://www.erlang-in-anger.com/&quot;&gt;Erlang in
Anger&lt;/a&gt;, had this to say on the topic.
[&lt;a href=&quot;https://ferd.ca/on-the-use-of-the-process-dictionary-in-erlang.html&quot;&gt;source&lt;/a&gt;]&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The process dictionary is not inherently evil, but it has many drawbacks that have been mentioned countless times already: it is harder to debug and reason about, it has different semantics than most of the language, it breaks when you try to send state to other processes without knowing it’s tied to the process’ very existence, it is not garbage collected until the process dies, it is hard to replace by a different key-value store and it angers people (I do consider this to be a negative). On the positive side, you have better update speed. On the neutral side, you have global access to some values, within the scope of the process: this can both be useful (static config) or dangerous (global scope!)&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Look for the tradeoffs you’re ready to make, what your application actually needs. Use the right tool for the right job and make sure the process-global aspect of it and the speed do warrant all the downsides of it. I hope this helps.&lt;/p&gt;
&lt;/blockquote&gt;
</description>
        <pubDate>Sun, 24 Sep 2017 09:20:45 -0600</pubDate>
        <link>http://brainlid.org/elixir/2017/09/24/elixir-processes-and-state-abuse.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2017/09/24/elixir-processes-and-state-abuse.html</guid>
        
        <category>elixir</category>
        
        <category>processes</category>
        
        <category>state</category>
        
        
        <category>elixir</category>
        
      </item>
    
      <item>
        <title>Elixir Processes and State - Recommended</title>
        <description>&lt;p&gt;&lt;em&gt;Taking the “happy path”&lt;/em&gt;
&lt;img src=&quot;/assets/img/felix-kayser-43337-750px.jpg&quot; alt=&quot;Taking the happy path Photo by Felix Kayser on Unsplash&quot; /&gt;&lt;/p&gt;

&lt;p&gt;In Elixir and Erlang, a process is where we keep our state.&lt;/p&gt;

&lt;p&gt;The story goes like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;a process starts with an initial state&lt;/li&gt;
  &lt;li&gt;the process waits for messages&lt;/li&gt;
  &lt;li&gt;send messages to the process to change it’s state&lt;/li&gt;
  &lt;li&gt;process modifies it’s state and passes itself the new version of it’s state&lt;/li&gt;
  &lt;li&gt;waits for messages (rinse and repeat)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;That’s it.&lt;/p&gt;

&lt;p&gt;There are a number of different interfaces to do this, but underneath it all,
they are all doing the same thing.&lt;/p&gt;

&lt;p&gt;The built-in ways look like this:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://hexdocs.pm/elixir/Kernel.html#spawn/3&quot;&gt;spawn&lt;/a&gt; a process&lt;/li&gt;
  &lt;li&gt;Use a &lt;a href=&quot;https://hexdocs.pm/elixir/GenServer.html&quot;&gt;GenServer&lt;/a&gt; behavior&lt;/li&gt;
  &lt;li&gt;Use an &lt;a href=&quot;https://hexdocs.pm/elixir/Agent.html&quot;&gt;Agent&lt;/a&gt; behavior (a subset of &lt;code class=&quot;highlighter-rouge&quot;&gt;GenServer&lt;/code&gt; functionality)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Why is this a recommended pattern?&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;it is efficient&lt;/li&gt;
  &lt;li&gt;it is easy to write pure functions that test the behavior (given the same input, the same output results)&lt;/li&gt;
  &lt;li&gt;it is common convention, others will understand what you are doing&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;examples-of-recommended-style&quot;&gt;Examples of Recommended Style&lt;/h2&gt;

&lt;p&gt;I setup a simple Github project that makes it easy to play with these
approaches.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/brainlid/meetup_process_state&quot;&gt;https://github.com/brainlid/meetup_process_state&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;basic-spawn-example&quot;&gt;Basic Spawn Example&lt;/h3&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SpawnBasic&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;kn&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Starting separate process with initial state: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;spawn&lt;/span&gt; &lt;span class=&quot;bp&quot;&gt;__MODULE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:main_loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;main_loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;main_loop state: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;new_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;receive&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
            &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
              &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Received :add message: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
            &lt;span class=&quot;n&quot;&gt;_&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt;
              &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Received some other message. State unchanged.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
              &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;
          &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;main_loop&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;new_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;defp&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;When we call &lt;code class=&quot;highlighter-rouge&quot;&gt;start&lt;/code&gt;, it spawns a new process. That process sets up it’s initial
state and calls &lt;code class=&quot;highlighter-rouge&quot;&gt;main_loop&lt;/code&gt;. There is nothing special about this function name.
I just picked something. The process then calls &lt;code class=&quot;highlighter-rouge&quot;&gt;receive&lt;/code&gt;. This blocks the
process until it receives a message. This example only responds to a message of
&lt;code class=&quot;highlighter-rouge&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;:add,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;err&quot;&gt;number&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;. When that message is received, it modifies the state and uses
“tail recursion” to call itself again with the new state.&lt;/p&gt;

&lt;p&gt;Experiment by sending messages and seeing the log output in the console. The
Logger config was customized to output the &lt;code class=&quot;highlighter-rouge&quot;&gt;pid&lt;/code&gt; as part of the metadata. This
makes it easier to see which process is running which commands.&lt;/p&gt;

&lt;p&gt;You might see something like this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;SpawnBasic&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;08.640&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.114&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Starting&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;separate&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;process&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;08.640&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.116&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;main_loop&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#PID&amp;lt;0.116.0&amp;gt;&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;12.469&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.116&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Received&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;12.469&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.116&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;main_loop&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;send&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;14.758&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.116&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Received&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;message:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;47&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;14.758&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.116&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;n&quot;&gt;main_loop&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;If you open Observer and inspect the process (in this example it would be
0.116.0) the “State” tab will show you “Information could not be retrieved,
system messages may not be handled by this process.” This basic spawn works as
intended, but it doesn’t support being inspected and handling system-level
messages. That’s one reason it’s better to use a GenServer.&lt;/p&gt;

&lt;h3 id=&quot;genserver-example&quot;&gt;GenServer Example&lt;/h3&gt;

&lt;p&gt;The &lt;a href=&quot;https://hexdocs.pm/elixir/GenServer.html&quot;&gt;GenServer&lt;/a&gt; approach is preferred.
It makes it easier to supervise the process and it has built-in support for
handling system messages.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;k&quot;&gt;defmodule&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;kn&quot;&gt;require&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;
      &lt;span class=&quot;kn&quot;&gt;use&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GenServer&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# Client&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Starting genserver with initial state: &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;GenServer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;bp&quot;&gt;__MODULE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Sending :add message&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;GenServer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

      &lt;span class=&quot;c1&quot;&gt;# Server (callbacks)&lt;/span&gt;

      &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;handle_call&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_from&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;Adding &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; to state.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;new_state&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;no&quot;&gt;Logger&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;New state is &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;inspect&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_state&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:reply&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;current&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;increment&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;new_state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here’s an example of how to interact with it in IEx.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;:observer&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# examine the &quot;state&quot; of the process&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You might see something like this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;alias&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;ProcessState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;start&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;29.725&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.114&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Starting&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;genserver&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;with&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;initial&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;state:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:ok&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#PID&amp;lt;0.117.0&amp;gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;32.965&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.114&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Sending&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;32.965&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.117&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Adding&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;32.965&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.117&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;New&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;iex&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;GenServerState&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;add&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;11&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;m&quot;&gt;21&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;38.822&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.114&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Sending&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:add&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;message&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;38.822&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.117&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;Adding&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;11&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;

    &lt;span class=&quot;m&quot;&gt;19&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;59&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;38.822&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;pid&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&amp;lt;&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0.117&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;info&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;  &lt;span class=&quot;no&quot;&gt;New&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;state&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;is&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;counter:&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;21&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Note the &lt;code class=&quot;highlighter-rouge&quot;&gt;pid&lt;/code&gt; responsible for running each line? All the same things are
happening here that are happening in the spawn example. The GenServer approach
makes it less explicit and adds support for handling other system messages.&lt;/p&gt;

&lt;p&gt;Running Observer, I found the pid (0.117.0 in my case) in the “Processes” tab.
Inspecting that process, the “State” tab looks like this.&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/img/2017-09-23-gen_server_observer.png&quot; alt=&quot;observer inspecting GenServer State&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The last line shows the “state” structure in the GenServer process.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Using the GenServer or Agent approach for storing runtime state in your Elixir
application is the standard, recommended way. They have built-in support for
being supervised. There is built-in support for handling system-level events.
Observer understands them and can work with them natively. Most importantly
perhaps, the functions can be “pure” and predictable. Given the same input, the
same output is returned.&lt;/p&gt;

&lt;p&gt;This is the “clean” version of managing state in a process.&lt;/p&gt;
</description>
        <pubDate>Fri, 22 Sep 2017 20:20:45 -0600</pubDate>
        <link>http://brainlid.org/elixir/2017/09/22/elixir-processes-and-state-recommended.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2017/09/22/elixir-processes-and-state-recommended.html</guid>
        
        <category>elixir</category>
        
        <category>processes</category>
        
        <category>state</category>
        
        
        <category>elixir</category>
        
      </item>
    
      <item>
        <title>Security Scanning Your Phoenix App</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://github.com/nccgroup/sobelow&quot;&gt;Sobelow&lt;/a&gt; is a security-focused static
analysis tool for the Phoenix framework. It is produced by &lt;a href=&quot;https://www.nccgroup.trust/us/&quot;&gt;NCC
Group&lt;/a&gt;, a cyber-security firm whose roots go
back to June 1999.&lt;/p&gt;

&lt;p&gt;At the time of this writing, the current version is 0.3.6 and it has been
gaining traction in the Elixir/Phoenix communities.&lt;/p&gt;

&lt;h2 id=&quot;why-run-security-scans&quot;&gt;Why Run Security Scans?&lt;/h2&gt;

&lt;p&gt;First, it should be a matter of personal responsibility to your product and your
users that you try to protect your application and your user’s data.&lt;/p&gt;

&lt;p&gt;Second, various certifications like PCI Compliance can require things like
automated static-analysis security scans or security code reviews of all changes
to the system.&lt;/p&gt;

&lt;p&gt;Third, what coding habits do you have that might be a security risk? Sobelow can
be that third-party reviewer to challenge your long-held assumptions.&lt;/p&gt;

&lt;p&gt;I work at a fast-paced FinTech startup with agile workflows. The best option is
to have security scans automatically performed on PRs before they are merged.
Some benefits to having them automated is you don’t forget to run the checks and
it helps identify new code changes that could have security problems.&lt;/p&gt;

&lt;h2 id=&quot;install-options&quot;&gt;Install Options&lt;/h2&gt;

&lt;p&gt;The project recommends installing it outside of the project to be scanned like
this.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ mix archive.install hex sobelow&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;This works well when you want to scan other people’s projects without modifying
their dependencies.&lt;/p&gt;

&lt;p&gt;It also works to add it to your project’s &lt;code class=&quot;highlighter-rouge&quot;&gt;mix.exs&lt;/code&gt; if that makes more sense for
your situation.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;deps&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;[{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:sobelow&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;~&amp;gt; 0.3&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;only:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:dev&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]}]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h2 id=&quot;running-a-scan&quot;&gt;Running a Scan&lt;/h2&gt;

&lt;p&gt;Running your first scan is easy.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ mix sobelow&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;There are a number of command-line options and new options were recently added
so it is worth checking for current documentation.&lt;/p&gt;

&lt;h2 id=&quot;we-need-code-to-scan&quot;&gt;We Need Code to Scan!&lt;/h2&gt;

&lt;p&gt;I did a quick Github search for OpenSource Phoenix applications that I could use
for this post and found one under active development. This will work perfectly!&lt;/p&gt;

&lt;p&gt;Setup steps before we can test &lt;code class=&quot;highlighter-rouge&quot;&gt;sobelow&lt;/code&gt; on the project.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Clone the project locally&lt;/li&gt;
  &lt;li&gt;Make it able to compile&lt;/li&gt;
  &lt;li&gt;Nothing more needed! It’s “static-analysis” remember?&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Run &lt;code class=&quot;highlighter-rouge&quot;&gt;sobelow&lt;/code&gt; on the project…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;    $ mix sobelow

    ##############################################
    #                                            #
    #          Running Sobelow - v0.3.6          #
    #  Created by Griffin Byatt - @griffinbyatt  #
    #     NCC Group - https://nccgroup.trust     #
    #                                            #
    ##############################################

    Missing CSRF Protections - High Confidence
    Pipeline: browser:4

    -----------------------------------------------

    HTTPS Not Enabled - High Confidence

    -----------------------------------------------

    Known Vulnerable Dependency - Plug v1.3.4

    -----------------------------------------------

    Known Vulnerable Dependency - Phoenix v1.2.1

    -----------------------------------------------

    Directory Traversal in `File.read!` - High Confidence
    File: web/controllers/contact_controller.ex - create_nested_data:175
    Variable: temp_file

    -----------------------------------------------

    Directory Traversal in `File.rm!` - High Confidence
    File: web/controllers/contact_controller.ex - create_nested_data:175
    Variable: temp_file

    -----------------------------------------------

    Directory Traversal in `File.read!` - High Confidence
    File: web/controllers/contact_controller.ex - view_uploaded_data:159
    Variable: temp_file

    -----------------------------------------------

    Directory Traversal in `File.read!` - Medium Confidence
    File: web/controllers/contact_controller.ex - import_data:135
    Variable: temp_file

    -----------------------------------------------

    Directory Traversal in `File.rm!` - Medium Confidence
    File: web/controllers/contact_controller.ex - import_data:135
    Variable: temp_file

    -----------------------------------------------

    Insecure use of `File` and `Path` - Low Confidence
    File: web/controllers/contact_controller.ex - import_data:135
    Variable: upload

    -----------------------------------------------

    ... SCAN COMPLETE ...&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Unfortunately, the color coding doesn’t translate to my copy of the
text here. So just note that it is sorted with “High Confidence” items higher
up then descending to “Medium” and “Low”. The colors change accordingly.&lt;/p&gt;

&lt;p&gt;Interesting output! Now what does it mean? It is worth noting what the Sobelow
project says about “False Positives”:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Sobelow favors over-reporting versus under-reporting. As such, you may find a
number of false positives in a typical scan. These findings may be individually
ignored by adding a @sobelow_skip mark, along with a list of modules, before the
function definition.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;So we need to check them personally and determine if it is a problem or not.&lt;/p&gt;

&lt;p&gt;Let’s try out the command-line option &lt;code class=&quot;highlighter-rouge&quot;&gt;--with-code&lt;/code&gt; and see if that helps
give context to the warnings. I won’t include the full output for brevity’s sake.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;    Missing CSRF Protections - High Confidence
    Pipeline: browser:4


    pipeline(:browser) do
      plug(:accepts, [&quot;html&quot;])
      plug(:fetch_session)
      plug(:fetch_flash)
      plug(:put_secure_browser_headers)
    end&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;I double-checked the router file and yes, it is missing the &lt;code class=&quot;highlighter-rouge&quot;&gt;plug
:protect_from_forgery&lt;/code&gt; call you would otherwise expect.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;    Known Vulnerable Dependency - Plug v1.3.4
    Details: Header Injection
    CVE: TBA

    -----------------------------------------------

    Known Vulnerable Dependency - Phoenix v1.2.1
    Details: Arbitrary URL Redirect
    CVE: TBA&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Well that’s nice! A recent &lt;code class=&quot;highlighter-rouge&quot;&gt;sobelow&lt;/code&gt; feature is checking for known
vulnerabilities in the project’s dependencies. And yes, the project’s &lt;code class=&quot;highlighter-rouge&quot;&gt;mix.exs&lt;/code&gt;
file is pinned to an older phoenix version. Time to upgrade!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:phoenix&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;~&amp;gt; 1.2.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Here’s another one with a good code sample.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;no&quot;&gt;Directory&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Traversal&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;in&lt;/span&gt; &lt;span class=&quot;err&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read!&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;`&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;High&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Confidence&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;File:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;web&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;controllers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;contact_controller&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;ex&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;view_uploaded_data:&lt;/span&gt;&lt;span class=&quot;m&quot;&gt;159&lt;/span&gt;
    &lt;span class=&quot;ss&quot;&gt;Variable:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp_file&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;view_uploaded_data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;mapping&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;temp_file&quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}))&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;table&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;tmp/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp_file&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.csv&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExCsv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;parse!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ExCsv&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;with_headings&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&amp;gt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;to_list&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;total_rows&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;count&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;1&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;contact_headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;contact&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;organization_headers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Map&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;keys&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;organization&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;first_row&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Enum&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;at&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;table&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;m&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;contact_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;contact&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first_row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csv_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;organization_values&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;for&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;db_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;csv_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;-&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mapping&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;organization&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;])&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;first_row&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;csv_col&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;json&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;conn&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;%{&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;contact_headers:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contact_headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;organization_headers:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;organization_headers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;contact_values:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;contact_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;organization_values:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;organization_values&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;temp_file:&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;temp_file&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Again, the coloring doesn’t come across here. But the code being pointed out is this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;no&quot;&gt;File&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;read!&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sd&quot;&gt;&quot;&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;tmp/&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;temp_file&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;.csv&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;After checking the router, it is clear that this is indeed taking user submitted
data and interpolating that text into a command-line path. This means submitting
a “temp_file” value like “&lt;code class=&quot;highlighter-rouge&quot;&gt;../somewhere/else&lt;/code&gt;” poses a risk of accessing data
from anywhere on disk. I verified in the router that in order to even make this
call, you must be an authenticated user. This prompts the question, “How much do
you trust &lt;em&gt;all&lt;/em&gt; of your users?”&lt;/p&gt;

&lt;p&gt;I notified the project on Github of the issues and they have already addressed
them.&lt;/p&gt;

&lt;p&gt;It is also interesting how &lt;code class=&quot;highlighter-rouge&quot;&gt;sobelow&lt;/code&gt; displays the function as
&lt;code class=&quot;highlighter-rouge&quot;&gt;def(view_uploaded_data(...))&lt;/code&gt;. Looking at the actual file, it was as
you’d expect with &lt;code class=&quot;highlighter-rouge&quot;&gt;def view_uploaded_data(...)&lt;/code&gt;. I guess that’s exposing the
reality that &lt;code class=&quot;highlighter-rouge&quot;&gt;def&lt;/code&gt; is an Elixir macro. :)&lt;/p&gt;

&lt;p&gt;Now you’ve seen some real-world examples of how &lt;code class=&quot;highlighter-rouge&quot;&gt;sobelow&lt;/code&gt; can help your project.&lt;/p&gt;

&lt;h2 id=&quot;umbrella-projects&quot;&gt;Umbrella Projects&lt;/h2&gt;

&lt;p&gt;Sobelow is only designed for scanning Phoenix applications. So it doesn’t scan a
standard &lt;code class=&quot;highlighter-rouge&quot;&gt;mix new&lt;/code&gt; project. I follow the pattern where my projects are umbrella
applications with the Phoenix project being generated without Ecto. This really
reduces the utility of sobelow.&lt;/p&gt;

&lt;p&gt;Running it from the root of my project it returns this…&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;&lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mix&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sobelow&lt;/span&gt;
&lt;span class=&quot;no&quot;&gt;This&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;does&lt;/span&gt; &lt;span class=&quot;ow&quot;&gt;not&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;appear&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;be&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Phoenix&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;application&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Luckily, the &lt;code class=&quot;highlighter-rouge&quot;&gt;--root&lt;/code&gt; option lets me specify the path to the Phoenix app in my
project.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-elixir&quot; data-lang=&quot;elixir&quot;&gt;    &lt;span class=&quot;err&quot;&gt;$&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mix&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;sobelow&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;--&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;root&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;apps&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;my_web&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;/&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;##############################################&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#                                            #&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#          Running Sobelow - v0.3.6          #&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#  Created by Griffin Byatt - @griffinbyatt  #&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#     NCC Group - https://nccgroup.trust     #&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;#                                            #&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;##############################################&lt;/span&gt;

    &lt;span class=&quot;no&quot;&gt;HTTPS&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Not&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Enabled&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;High&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Confidence&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;-----------------------------------------------&lt;/span&gt;

    &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;SCAN&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;COMPLETE&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;...&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;It’s totally true. My personal project that lives only on my machine hasn’t been
setup for HTTPS yet. But, it’s a nice reminder that this should be a priority
before I deploy outside of my home.&lt;/p&gt;

&lt;p&gt;But it found nothing else. Since all my Ecto queries are done in other apps
where the business logic lives, how comfortable should I be that this didn’t
find anything? I’m not sure. Sobelow has been advancing quickly recently. I’m
hopeful that it will grow in sophistication over time.&lt;/p&gt;

&lt;h2 id=&quot;work-project-scan-results&quot;&gt;Work Project Scan Results&lt;/h2&gt;

&lt;p&gt;I started using Sobelow on our backend system at work.
Now, I got the same “HTTPS Not Enabled”. However, in this case it isn’t a
problem. Our production deployment has the web application behind load-balancers
that are terminating the HTTPS connection. So our app doesn’t have that
responsibility. How do we tell Sobelow this is okay?&lt;/p&gt;

&lt;h3 id=&quot;disable-a-check&quot;&gt;Disable a Check&lt;/h3&gt;

&lt;p&gt;To disable the “HTTPS Not Enabled” check, I searched the sobelow project code
for some error text and found it easily enough.&lt;/p&gt;

&lt;p&gt;This one is not a specific line of code to disable, it is turning off the check.
The &lt;code class=&quot;highlighter-rouge&quot;&gt;-i&lt;/code&gt; is to “ignore” that check.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ mix sobelow -i Config.HTTPS&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;h3 id=&quot;valid-finds&quot;&gt;Valid Finds&lt;/h3&gt;

&lt;p&gt;Sobelow found a valid “Unsafe &lt;code class=&quot;highlighter-rouge&quot;&gt;String.to_atom&lt;/code&gt; - High Confidence” issue. At
work, many of the backend developers are new to Elixir. You can’t expect
everyone to be familiar with the details of a new language and its runtime. A
member of our team took client provided raw param data and performed
&lt;code class=&quot;highlighter-rouge&quot;&gt;String.to_atom&lt;/code&gt; on it. Atoms in Elixir are like Symbols in Ruby. Elixir atoms
are not garbage collected. This allows a malicious user to arbitrarily create
them through an HTTP POST which can be abused to consume system resources until
the server crashes. Resulting in a “denial of service” attack.&lt;/p&gt;

&lt;p&gt;This find lets us have an “education moment”. So it works!&lt;/p&gt;

&lt;h2 id=&quot;automated-scanning&quot;&gt;Automated Scanning&lt;/h2&gt;

&lt;p&gt;The option &lt;code class=&quot;highlighter-rouge&quot;&gt;--exit&lt;/code&gt; returns a non-zero return code when problems are found. This
makes it easy for an automated system to “fail” the process when a new
vulnerability is introduced.&lt;/p&gt;

&lt;p&gt;From the docs:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;The exit option accepts a confidence threshold (low, medium, or high), and
will return a non-zero exit status at or above that threshold.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ mix sobelow --exit Low&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;So our project at work can run the tests on the multiple phoenix applications
in the umbrella and automatically fail the code checks when new problems are
introduced.&lt;/p&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;Sobelow is the first static-analysis security scanner for Phoenix that I’m aware
of. I looked around a lot. At work, we have PCI Compliance requirements in
addition to our desire to have a completely secure system. Sobelow came along
at the perfect time for us. It has become part of our automated processes for
testing code quality.&lt;/p&gt;

&lt;p&gt;Give it a try on your Phoenix projects and share your results!&lt;/p&gt;
</description>
        <pubDate>Wed, 14 Jun 2017 22:20:45 -0600</pubDate>
        <link>http://brainlid.org/elixir/2017/06/14/security-scanning-phoenix.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2017/06/14/security-scanning-phoenix.html</guid>
        
        <category>elixir</category>
        
        <category>security</category>
        
        <category>phoenix</category>
        
        
        <category>elixir</category>
        
      </item>
    
      <item>
        <title>History in IEx between sessions</title>
        <description>&lt;p&gt;When working with Elixir in an IEx console session, sometimes it is painful that it forgets everything between sessions!&lt;/p&gt;

&lt;p&gt;There is a simple Github project that fixes this!&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;git clone https://github.com/ferd/erlang-history.git
cd erlang-history
sudo make install&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;You can read more about it:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/ferd/erlang-history&quot;&gt;Project Github Page&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://zen.id.au/how-to-make-the-elixir-shell-iex-save-history/&quot;&gt;Other Blog Post&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://stackoverflow.com/questions/22426716/how-to-save-log-the-output-of-the-iex-shell-to-get-persistent-command-history/28514369#28514369&quot;&gt;Stack Overflow Answer&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;This project patches your local Erlang install to add history support. You will have to re-run this process after updating your Erlang version.&lt;/p&gt;

&lt;p&gt;I cannot personally guarantee the code. Since it clones the repo each time it is run, you should check for any changes since the last time you audited it.&lt;/p&gt;
</description>
        <pubDate>Wed, 22 Feb 2017 04:45:45 -0700</pubDate>
        <link>http://brainlid.org/elixir/2017/02/22/elixir-iex-history.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2017/02/22/elixir-iex-history.html</guid>
        
        <category>erlang</category>
        
        <category>elixir</category>
        
        
        <category>elixir</category>
        
      </item>
    
      <item>
        <title>Atom Editor for Elixir Development (Revisited)</title>
        <description>&lt;p&gt;A lot has changed in the Elixir community since I wrote my &lt;a href=&quot;/elixir/2015/11/12/atom-editor-and-elixir.html&quot;&gt;previous post&lt;/a&gt; on this topic.&lt;/p&gt;

&lt;p&gt;It’s time to update what Atom plugins work well for Elixir development.&lt;/p&gt;

&lt;h2 id=&quot;atoms-elixir-development-plugins&quot;&gt;Atom’s Elixir Development Plugins&lt;/h2&gt;

&lt;p&gt;The number of needed plugins has gone down. That’s a good thing! It means that the quality of the options is higher. I’m breaking this into 2 categories.&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;#must-have&quot;&gt;Must have&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;#optional&quot;&gt;Optional&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;NOTE: Install these plugins through Atom’s Settings &amp;gt; Install. See the
&lt;a href=&quot;https://atom.io/&quot;&gt;Atom Editor&lt;/a&gt; website for getting started with Atom.&lt;/p&gt;

&lt;h3 id=&quot;a-namemust-havea-must-have-elixir-plugins&quot;&gt;&lt;a name=&quot;must-have&quot;&gt;&lt;/a&gt; Must Have Elixir Plugins&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://atom.io/packages/language-elixir&quot;&gt;language-elixir&lt;/a&gt;&lt;/strong&gt; - Syntax support. Really, you have to have this.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://atom.io/packages/atom-elixir&quot;&gt;atom-elixir&lt;/a&gt;&lt;/strong&gt; - Advanced code completion and much, much more.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;The new one here is &lt;strong&gt;atom-elixir&lt;/strong&gt;. It wasn’t available the last time I reviewed the options.
It does such a good job that it replaces multiple other plugins.&lt;/p&gt;

&lt;p&gt;Here’s a little on how it works. There is a project called &lt;a href=&quot;https://github.com/tonini/alchemist.el&quot;&gt;Alchemist&lt;/a&gt;
that was created for supporting Elixir in Emacs. A spin-off project (by the same author)
called &lt;a href=&quot;https://github.com/tonini/alchemist-server&quot;&gt;alchemist-server&lt;/a&gt; aims to make
that same Elixir information available in an editor-independent way. The atom-elixir
plugin leverages alchemist-server to do all the hard work on getting Elixir
intelligence and makes it accessible in Atom.&lt;/p&gt;

&lt;p&gt;This is meaningful to me because it indicates that support and features are more likely
to continue.&lt;/p&gt;

&lt;p&gt;I want to draw special attention to the &lt;strong&gt;atom-elixir&lt;/strong&gt; plugin because it still has relatively low download numbers but is my personal go-to tool for Elixir development. I believe more people need to know about it. And no, I have nothing to do with the project or the people involved. :)&lt;/p&gt;

&lt;h3 id=&quot;take-a-look&quot;&gt;Take a Look…&lt;/h3&gt;

&lt;p&gt;Screenshot of the auto-completion window:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/atom/2017-01-22-elixir-code-completion.png&quot; alt=&quot;Elixir auto-completion window&quot; /&gt;&lt;/p&gt;

&lt;p&gt;Screenshot of the documentation tab that opens on demand:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;/assets/atom/2017-01-22-elixir-show-docs.png&quot; alt=&quot;Elixir documentation tab&quot; /&gt;&lt;/p&gt;

&lt;h3 id=&quot;code-navigation-feature&quot;&gt;Code Navigation Feature&lt;/h3&gt;

&lt;p&gt;Check the shortcuts for your platform, but with a cursor on a function, I press
&lt;kbd&gt;atl-down&lt;/kbd&gt; (arrow) and it performs a “goto-definition”. I can then jump again and
again going deeper. Then, using &lt;kbd&gt;alt-up&lt;/kbd&gt;, I can pop the stack and jump back to where
my cursor was at the previous point. This jumping back keeps popping the stack to eventually return me to the first jump point. I really love this feature!&lt;/p&gt;

&lt;h3 id=&quot;caveat&quot;&gt;Caveat&lt;/h3&gt;

&lt;p&gt;Atom allows you to open multiple projects at the same time. They show up in the
tree with different roots. However, the code-completion doesn’t work with
multiple projects open like that. It runs 1 alchemist server and it can’t cover
both projects at the same time. However, it works fine with an Umbrella project.&lt;/p&gt;

&lt;h3 id=&quot;a-nameoptionala-optional-elixir-plugins&quot;&gt;&lt;a name=&quot;optional&quot;&gt;&lt;/a&gt; Optional Elixir Plugins&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://atom.io/packages/linter-elixirc&quot;&gt;linter-elixirc&lt;/a&gt;&lt;/strong&gt; - Displays in-line the error with parsed out error message text. Runs after saving the file. Works by compiling the project and displaying the first error it encounters. Works well. In the past is has reported some false positives for me but it appears to be doing better as of late.&lt;/li&gt;
  &lt;li&gt;&lt;strong&gt;&lt;a href=&quot;https://atom.io/packages/linter&quot;&gt;linter&lt;/a&gt;&lt;/strong&gt; - a base linter provider that other language specific linters build on. Used by “linter-elixirc”.&lt;/li&gt;
&lt;/ul&gt;

&lt;h2 id=&quot;conclusion&quot;&gt;Conclusion&lt;/h2&gt;

&lt;p&gt;It’s been fun working in the Elixir ecosystem and community. Lots of great
advancements have been made in a relatively short time. I can’t wait to see how things improve and change going forward!&lt;/p&gt;

&lt;p&gt;Here I highlighted a small number of Atom plugins that help with developing Elixir
applications. If you aren’t already using &lt;strong&gt;atom-elixir&lt;/strong&gt;, you should try it out now.&lt;/p&gt;

&lt;p&gt;Want to share your favorite Elixir-related Atom plugin? Share it here!&lt;/p&gt;
</description>
        <pubDate>Mon, 20 Feb 2017 05:30:45 -0700</pubDate>
        <link>http://brainlid.org/elixir/2017/02/20/atom-editor-and-elixir-revisited.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2017/02/20/atom-editor-and-elixir-revisited.html</guid>
        
        <category>elixir</category>
        
        <category>atom</category>
        
        
        <category>elixir</category>
        
      </item>
    
      <item>
        <title>Atom and CTAGS not in PATH Error</title>
        <description>&lt;p&gt;I use the &lt;a href=&quot;https://atom.io/&quot;&gt;Atom Editor&lt;/a&gt; on Linux. Arch Linux specifically. Atom has a nice feature of &lt;kbd&gt;ctrl-R&lt;/kbd&gt; to view the symbols in the current file. This makes it easy to jump to a function or declaration in the current file.&lt;/p&gt;

&lt;p&gt;For the past while, it’s been broken for me. I decided it was time to dig in and solve it.&lt;/p&gt;

&lt;p&gt;I learned that &lt;code class=&quot;highlighter-rouge&quot;&gt;ctags&lt;/code&gt; is now required to be provided by the system. This
&lt;a href=&quot;https://www.peterbe.com/plog/ctags-in-atom-on-osx&quot;&gt;blog post&lt;/a&gt; helped identify
that and offers some great tips! It references this &lt;a href=&quot;http://stackoverflow.com/questions/20644939/python-ctags-subprocess-call-in-mac-osx/20645684#20645684&quot;&gt;SO answer&lt;/a&gt; too.&lt;/p&gt;

&lt;p&gt;For my Arch Linux install, I installed &lt;code class=&quot;highlighter-rouge&quot;&gt;ctags&lt;/code&gt;.&lt;/p&gt;

&lt;figure class=&quot;highlight&quot;&gt;&lt;pre&gt;&lt;code class=&quot;language-text&quot; data-lang=&quot;text&quot;&gt;$ sudo pacman -S ctags&lt;/code&gt;&lt;/pre&gt;&lt;/figure&gt;

&lt;p&gt;Yay! Now running &lt;kbd&gt;ctrl-R&lt;/kbd&gt; on a file parses and shows the symbols/functions
in the file. This was particularly a problem for me with Elixir source files.&lt;/p&gt;

&lt;p&gt;However, the &lt;kbd&gt;ctrl-shift-R&lt;/kbd&gt; for project-wide searching comes up empty.&lt;/p&gt;

&lt;p&gt;The same blog post shows how to have the &lt;code class=&quot;highlighter-rouge&quot;&gt;ctags&lt;/code&gt; rebuilt for the project on checkout of a different branch. (Using githooks).&lt;/p&gt;

&lt;p&gt;Mystery solved. Phew!&lt;/p&gt;
</description>
        <pubDate>Mon, 20 Feb 2017 04:30:45 -0700</pubDate>
        <link>http://brainlid.org/elixir/2017/02/20/ctags-in-atom.html</link>
        <guid isPermaLink="true">http://brainlid.org/elixir/2017/02/20/ctags-in-atom.html</guid>
        
        <category>atom</category>
        
        <category>elixir</category>
        
        
        <category>elixir</category>
        
      </item>
    
  </channel>
</rss>
