<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:dc="http://purl.org/dc/elements/1.1/">
  <channel>
    <title>DEV Community: Brandon Weaver</title>
    <description>The latest articles on DEV Community by Brandon Weaver (@baweaver).</description>
    <link>https://dev.to/baweaver</link>
    <image>
      <url>https://res.cloudinary.com/practicaldev/image/fetch/s--Q7LEIss2--/c_fill,f_auto,fl_progressive,h_90,q_auto,w_90/https://dev-to-uploads.s3.amazonaws.com/uploads/user/profile_image/129384/bc4c54aa-bacc-4804-8de6-edc3ff7a173b.png</url>
      <title>DEV Community: Brandon Weaver</title>
      <link>https://dev.to/baweaver</link>
    </image>
    <atom:link rel="self" type="application/rss+xml" href="https://dev.to/feed/baweaver"/>
    <language>en</language>
    <item>
      <title>Ruby in FantasyLand: SumsUp</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Tue, 24 May 2022 06:05:56 +0000</pubDate>
      <link>https://dev.to/baweaver/ruby-in-fantasyland-sumsup-2266</link>
      <guid>https://dev.to/baweaver/ruby-in-fantasyland-sumsup-2266</guid>
      <description>&lt;p&gt;Javascript comes with this lovely little spec called &lt;a href="https://github.com/fantasyland/fantasy-land"&gt;Fantasy Land&lt;/a&gt; that defines certain type classes in Category Theory and how they interact.&lt;/p&gt;

&lt;p&gt;Years ago, when I was particularly interested in learning about Category Theory, Algebraic Types, and the lot of it I had stumbled upon a lovely series from &lt;a href="https://twitter.com/am_i_tom"&gt;Tom Harding&lt;/a&gt; called &lt;a href="http://www.tomharding.me/fantasy-land/"&gt;Fantas, Eel, and Specification&lt;/a&gt; which I got quite a bit of enjoyment from.&lt;/p&gt;

&lt;p&gt;This series, with the permission of &lt;a href="https://twitter.com/am_i_tom"&gt;Tom&lt;/a&gt;, is a reinterpretation of those posts in Ruby along with some of my own thoughts.&lt;/p&gt;

&lt;p&gt;With that said, let's get into it.&lt;/p&gt;

&lt;h2&gt;
  
  
  SumsUp
&lt;/h2&gt;

&lt;p&gt;The initial post that we're working from is the introduction into both data classes and sum types using &lt;a href="https://github.com/fantasyland/daggy"&gt;Daggy&lt;/a&gt;, and you can read the original post here:&lt;/p&gt;

&lt;p&gt;&lt;a href="http://www.tomharding.me/2017/03/03/fantas-eel-and-specification/"&gt;http://www.tomharding.me/2017/03/03/fantas-eel-and-specification/&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Now with Ruby we have a few different ideas we want to express. Whereas Daggy has &lt;code&gt;tagged&lt;/code&gt; and &lt;code&gt;taggedSum&lt;/code&gt; we have &lt;code&gt;Struct&lt;/code&gt; and &lt;code&gt;SumsUp.define&lt;/code&gt; instead. You can find more info on SumsUp &lt;a href="https://github.com/nahiluhmot/sums_up"&gt;here&lt;/a&gt;, but we'll be covering the general details in this post.&lt;/p&gt;

&lt;h2&gt;
  
  
  Struct vs Tagged
&lt;/h2&gt;

&lt;p&gt;The idea of Daggy's &lt;code&gt;tagged&lt;/code&gt; method is to create a succinct inline type. In Ruby we have &lt;code&gt;Struct&lt;/code&gt; which matches this use case, which you can compare:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="c1"&gt;//- A coordinate in 3D space.&lt;/span&gt;
&lt;span class="c1"&gt;//+ Coord :: (Int, Int, Int) -&amp;gt; Coord&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Coord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;daggy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Coord&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;x&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;y&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;z&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;

&lt;span class="c1"&gt;//- A line between two coordinates.&lt;/span&gt;
&lt;span class="c1"&gt;//+ Line :: (Coord, Coord) -&amp;gt; Line&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;daggy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;tagged&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Line&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;from&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;to&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;To the Ruby equivalent:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Coord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:to&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we really wanted to be precise we could even look into &lt;a href="https://sorbet.org/docs/tstruct"&gt;Sorbet Typed Structs&lt;/a&gt; for the sake of explicitness:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"sorbet-runtime"&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Coord&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Struct&lt;/span&gt;
  &lt;span class="kp"&gt;extend&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Sig&lt;/span&gt;

  &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;
  &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="ss"&gt;:y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;
  &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Integer&lt;/span&gt;

  &lt;span class="n"&gt;sig&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;params&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="no"&gt;Integer&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;returns&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;:)&lt;/span&gt;
    &lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="vi"&gt;@x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="vi"&gt;@y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="vi"&gt;@z&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Line&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;T&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Struct&lt;/span&gt;
  &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="ss"&gt;:from&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Coord&lt;/span&gt;
  &lt;span class="n"&gt;prop&lt;/span&gt; &lt;span class="ss"&gt;:to&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;Coord&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;path&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Line&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;from: &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;to: &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; &amp;lt;Coord x=2, y=3, z=4&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but that may be a matter for a later day, and an exercise left to the reader, though I would still recommend explicit classes if you find yourself writing methods on data objects like this.&lt;/p&gt;

&lt;p&gt;Anyways, that aside, we also need to know how to put basic methods on a &lt;code&gt;Struct&lt;/code&gt; as well, and there are two ways to do that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Coord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;z&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;struct Coord x=2, y=3, z=4&amp;gt;&lt;/span&gt;

&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:move_north&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;move_north&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;struct Coord x=1, y=4, z=3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Though honestly by that rate I would likely consider creating a class instead as this can get a bit complicated.&lt;/p&gt;

&lt;p&gt;Oh, and you can do this with &lt;code&gt;Struct&lt;/code&gt;, same as &lt;code&gt;new&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;struct Coord x=1, y=2, z=3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As another aside I tend to prefer &lt;code&gt;keyword_init&lt;/code&gt; as it makes things clearer:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Coord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;keyword_init: &lt;/span&gt;&lt;span class="kp"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;z: &lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;struct Coord x=1, y=2, z=3&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The intention of &lt;code&gt;tagged&lt;/code&gt; and &lt;code&gt;Struct&lt;/code&gt; are to give a name to a piece of data, and then give names to the fields or properties in that data, making them a handy quick utility for simpler cases. If you find yourself going beyond the simple, however, perhaps a class will make more sense.&lt;/p&gt;

&lt;h2&gt;
  
  
  taggedSum vs SumsUp define
&lt;/h2&gt;

&lt;p&gt;Now this one will be a bit more foreign. Starting with the example provided, &lt;code&gt;Bool&lt;/code&gt;, which can be true or false. That means a type with multiple constructors, or a "sum" type:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;daggy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taggedSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Bool&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;True&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[],&lt;/span&gt; &lt;span class="na"&gt;False&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and in Ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Bool&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SumsUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:false&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As neither have arguments the &lt;code&gt;define&lt;/code&gt; method accepts a list of variants without arguments. Where this gets more interesting is around ones that do:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;daggy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taggedSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;Shape&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="c1"&gt;// Square :: (Coord, Coord) -&amp;gt; Shape&lt;/span&gt;
  &lt;span class="na"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;topleft&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;bottomright&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;// Circle :: (Coord, Number) -&amp;gt; Shape&lt;/span&gt;
  &lt;span class="na"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;centre&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;radius&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and in Ruby:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SumsUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;# Square :: (Coord, Coord) -&amp;gt; Shape&lt;/span&gt;
  &lt;span class="ss"&gt;square: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"top_left"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"bottom_right"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;# Circle :: (Coord, Number) -&amp;gt; Shape&lt;/span&gt;
  &lt;span class="ss"&gt;circle: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"center"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"radius"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This gives us something quite foreign to work with, as now we're not working with inheritance but rather describing the shapes of data and how we interact with them:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="nx"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;translate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt;
  &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cata&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
      &lt;span class="na"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;topleft&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;bottomright&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;topleft&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="nx"&gt;bottomright&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;),&lt;/span&gt;

      &lt;span class="na"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;centre&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt;
        &lt;span class="nx"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="nx"&gt;centre&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;z&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="nx"&gt;radius&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;})&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="nx"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Square(Coord(5, 5, 3), Coord(6, 6, 3))&lt;/span&gt;

&lt;span class="nx"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;// Circle(Coord(7, 7, 7), 8)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and in Ruby this would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;Coord&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;z&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Shape&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SumsUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="c1"&gt;# Square :: (Coord, Coord) -&amp;gt; Shape&lt;/span&gt;
  &lt;span class="ss"&gt;square: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:top_left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:bottom_right&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;

  &lt;span class="c1"&gt;# Circle :: (Coord, Number) -&amp;gt; Shape&lt;/span&gt;
  &lt;span class="ss"&gt;circle: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:radius&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;top_left&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;bottom_right&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="no"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
          &lt;span class="n"&gt;top_left&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
          &lt;span class="n"&gt;bottom_right&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
        &lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;circle&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="no"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;center&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;z&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;radius&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Shape&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;square&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;variant Shape::Square&lt;/span&gt;
&lt;span class="c1"&gt;#     top_left=#&amp;lt;struct Coord x=3, y=3, z=1&amp;gt;,&lt;/span&gt;
&lt;span class="c1"&gt;#   bottom_right=#&amp;lt;struct Coord x=4, y=4, z=1&amp;gt;&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&lt;/span&gt;

&lt;span class="no"&gt;Shape&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;circle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Coord&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="mi"&gt;8&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;translate&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;6&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;variant Shape::Circle&lt;/span&gt;
&lt;span class="c1"&gt;#   center=#&amp;lt;struct Coord x=7, y=7, z=7&amp;gt;,&lt;/span&gt;
&lt;span class="c1"&gt;#   radius=8&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; As types stack up here though I do become more convinced that Sorbet may be a good addition to the following parts of this tutorial, and may see about working around &lt;code&gt;SumsUp&lt;/code&gt; or make a similar interface later. Feedback welcome.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the tutorial mentions Catamorphisms, as Daggy uses &lt;code&gt;cata&lt;/code&gt;, but to me this is very similar to pattern matching of which &lt;code&gt;SumsUp&lt;/code&gt; provides their own interface for. There may be an additional case for introducing pattern matching from Ruby 2.7+ into these interfaces later, but I digress again.&lt;/p&gt;

&lt;p&gt;The original article sums (ha) it up nicely by saying that sum types are types with multiple constructors.&lt;/p&gt;

&lt;h2&gt;
  
  
  Lists with Sums
&lt;/h2&gt;

&lt;p&gt;Now let's take a look at the final example mentioned here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;daggy&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;taggedSum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;List&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="na"&gt;Cons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;head&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="s1"&gt;tail&lt;/span&gt;&lt;span class="dl"&gt;'&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="na"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="p"&gt;})&lt;/span&gt;

&lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cata&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;Cons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
      &lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;head&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="nx"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;f&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;),&lt;/span&gt;

    &lt;span class="na"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Nil&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// A "static" method for convenience.&lt;/span&gt;
&lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="nx"&gt;xs&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;reduceRight&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
    &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;Nil&lt;/span&gt;
  &lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// And a conversion back for convenience!&lt;/span&gt;
&lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;prototype&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kd"&gt;function&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;this&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;cata&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;
    &lt;span class="na"&gt;Cons&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
      &lt;span class="nx"&gt;x&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;...&lt;/span&gt; &lt;span class="nx"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
    &lt;span class="p"&gt;],&lt;/span&gt;

    &lt;span class="na"&gt;Nil&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
  &lt;span class="p"&gt;})&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;// [3, 4, 5]&lt;/span&gt;
&lt;span class="nx"&gt;console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;log&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="nx"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="k"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="nx"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;toArray&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and the Ruby variant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;List&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;SumsUp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;define&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;cons: &lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:tail&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="ss"&gt;nil: &lt;/span&gt;&lt;span class="p"&gt;[])&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
        &lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;call&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;fn&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
      &lt;span class="k"&gt;end&lt;/span&gt;

      &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_a&lt;/span&gt;
    &lt;span class="n"&gt;match&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;head&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;tail&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
      &lt;span class="n"&gt;m&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nc"&gt;self&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;plain_list&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="c1"&gt;# Approximation of "reduce_right"&lt;/span&gt;
    &lt;span class="n"&gt;plain_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;cons&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;acc&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;])&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;lt;variant List::Cons head=1, tail=&lt;/span&gt;
&lt;span class="c1"&gt;#   &amp;lt;variant List::Cons head=2, tail=&lt;/span&gt;
&lt;span class="c1"&gt;#     &amp;lt;variant List::Cons head=3, tail=#&amp;lt;variant List::Nil&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;

&lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# &amp;lt;variant List::Cons head=3, tail=&lt;/span&gt;
&lt;span class="c1"&gt;#   &amp;lt;variant List::Cons head=4, tail=&lt;/span&gt;
&lt;span class="c1"&gt;#     &amp;lt;variant List::Cons head=5, tail=#&amp;lt;variant List::Nil&amp;gt;&amp;gt;&amp;gt;&amp;gt;&lt;/span&gt;

&lt;span class="no"&gt;List&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;from&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]).&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;to_a&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [3, 4, 5]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which gives us an interesting brief look into linked lists and some old lisp naming with &lt;a href="https://en.wikipedia.org/wiki/CAR_and_CDR"&gt;cons&lt;/a&gt;, though others might recognize &lt;code&gt;car&lt;/code&gt; and &lt;code&gt;car&lt;/code&gt; more readily.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;That about wraps us up on the first post. You can find the rest of &lt;a href="https://twitter.com/am_i_tom"&gt;Tom Harding&lt;/a&gt;'s lovely series &lt;a href="http://www.tomharding.me/fantasy-land/"&gt;here&lt;/a&gt; if you want spoilers, otherwise it may be prudent to convince me on Twitter not to try and hack together an algebraic datatype library with Sorbet-aware classes as I find myself quite tempted at the moment.&lt;/p&gt;

&lt;p&gt;The next post goes into type signatures, and from there we start a very interesting journey. While you may recognize some patterns and have your own intuition around them (cata/pattern matching looks like inheritance) keep an open mind for the moment and see where it takes us from here.&lt;/p&gt;

&lt;p&gt;Oh, and yes, this is a Monad tutorial in the end.&lt;/p&gt;

</description>
    </item>
    <item>
      <title>Tales of the Autistic Developer – The Politician</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Mon, 21 Mar 2022 00:08:20 +0000</pubDate>
      <link>https://dev.to/baweaver/tales-of-the-autistic-developer-the-politician-5aid</link>
      <guid>https://dev.to/baweaver/tales-of-the-autistic-developer-the-politician-5aid</guid>
      <description>&lt;p&gt;For those who don't know me, I'm autistic. I've been a developer for the better part of a decade.&lt;/p&gt;

&lt;p&gt;I didn't find out I was ASD until 19, and didn't reconcile with that until years later. These posts will be a combination of advice I've given to those who are like me, as well as a letter of sorts to my past self who could have used a lot of it.&lt;/p&gt;

&lt;p&gt;I write these posts in the hopes that someone like me will find value in knowing a very simple and very important truth about ASD:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You are not alone, and you are loved.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  The Politician
&lt;/h2&gt;

&lt;p&gt;If you were to ask any number of engineers what their most dreaded part of the job is it would not be surprising to see many answer politics. Bureaucracy, roadblocks, arguments everywhere, and all seemingly for no good reason other than to make things slow.&lt;/p&gt;

&lt;p&gt;Yet politics are perhaps the most important part of a software engineers job.&lt;/p&gt;

&lt;p&gt;Now autistic folks, we're not known for our social graces and understanding of fine nuance. If politics are such an integral part of the job it seems counterintuitive if not impossible that someone that's autistic has found any reasonable success there.&lt;/p&gt;

&lt;p&gt;That, dear friends, is precisely what this post is going to address.&lt;/p&gt;

&lt;h3&gt;
  
  
  Defining the Term
&lt;/h3&gt;

&lt;p&gt;To start: when I say politics what exactly do I mean? How do we define that for the sake of this article?&lt;/p&gt;

&lt;p&gt;We will be taking a very narrow focus on corporate politics at scale, and how they relate to team dynamics in a company at varying levels.&lt;/p&gt;

&lt;p&gt;We will &lt;em&gt;not&lt;/em&gt; be addressing global politics and how that relates to corporate, as that's deserving of a much longer post with far more nuance and attention than I'm capable of giving it at the moment. Sufficient to say this type is exceptionally important, and companies that pretend otherwise do so to their folly.&lt;/p&gt;

&lt;h2&gt;
  
  
  The New Politician - Local Scope
&lt;/h2&gt;

&lt;p&gt;When you're new to a job your focus is exceptionally localized and the politics you tend to be exposed to are likewise exceptionally localized. When I was at this level I saw a problem and I solved it, simple as that. Whenever someone stopped me from doing so or changed my trajectory I would scowl off and complain about politics, rather than take time to understand what was really going on.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;This led to a lot of problems, as I would very frequently feel betrayed or otherwise ignored whenever my work would dramatically shift, assuming that those above me didn't get it. When I felt this I would start raising arguments and advocate very harshly for what I believed should be done.&lt;/p&gt;

&lt;p&gt;I would broker no discussion, and fail to listen, because in my mind I knew what needed to be done and others just didn't get it yet. Because of how fixated I became on localized problems I missed the much wider picture of the business value the team was meant to deliver, and the strategic direction of my leadership.&lt;/p&gt;

&lt;p&gt;Likewise I did not want to be involved in all of these meetings about planning, backlog grooming, quarterly roadmapping, or other strategic meetings. I'd found them to be a massive waste of time when we could just work on what was in front of us and the very obvious problems as I saw them.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;A recurring theme throughout my posts, and one thing that I want to repeat as many times as necessary:&lt;/p&gt;

&lt;p&gt;Listen, then listen more, then make absolutely sure you've heard and listened again before opining.&lt;/p&gt;

&lt;p&gt;I had to start to learn what the wider picture was of the team and where they were headed, and how my work fit into that picture. Once I started to see that picture it made a lot more sense why work I had thought was important did not get prioritized, and why it seemed that I was constantly thrashing in my job instead of getting things done.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Strength
&lt;/h3&gt;

&lt;p&gt;Perhaps ironically my stubbornness and insistence on seeing something through led to a very unusual strength that's been commented on even up to today: tenacity.&lt;/p&gt;

&lt;p&gt;If I truly believe something is an issue I fully intend to pursue it and make sure it's fixed.&lt;/p&gt;

&lt;p&gt;When I learned to start listening I learned which issues were actually issues, and which ones were me not understanding the situation. It also taught me how to frame issues so that they would be prioritized by aligning myself with management and leads to show why it should be valued over other tasks.&lt;/p&gt;

&lt;p&gt;It was also the start of me seeing business value in what I did and how that translated into my teams deliverables.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Experienced Politician - Team Scope
&lt;/h2&gt;

&lt;p&gt;Once you've had a few years to mature as an engineer, and before you get to senior, you fall into one of the most dangerous parts of your career. It's a valley where one can presume expertise and knowledge where it isn't, and because of that you foster exceptionally strong opinions. Any of the strengths from the last section can become exceptional weaknesses if leveraged wrongly.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;The buried lede in the previous strength section is whether I truly believed something to be an issue. Given how self-righteous I was in the past you can imagine this was a very very bad idea as it would lead me to advocating exceptionally strongly for things that weren't really issues.&lt;/p&gt;

&lt;p&gt;Even worse, now I had enough sense to frame the case in such a way that I could potentially get the work roadmapped whether or not it made sense.&lt;/p&gt;

&lt;p&gt;I say this is a dangerous period as you have just enough experience to make a case, but not enough maturity to do so wisely yet. We mistake knowledge for wisdom, and with it the discretion that should be there to prevent self-righteous crusades and tilting at windmills.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;Remember the solution to the last section? Listening. It's a lesson that bears repeating daily if not hourly or minutely, perhaps even more frequently. The higher level you become the more fatal it is not to listen and go along with creating your own solutions without input from others.&lt;/p&gt;

&lt;p&gt;This was the stage of my career where I begun to form networks of friends, coworkers, organizational teammates, and company experts. Through them I could check myself to make sure what I was doing made sense, vet ideas, and qualify if this was something that was truly an issue or if I was just particularly worked up that day.&lt;/p&gt;

&lt;p&gt;It forced a reliance on my team, rather than acting out as an individual apart from them, even though leveling scope would have you believe self-sufficiency is the ultimate goal.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Strength
&lt;/h3&gt;

&lt;p&gt;Perhaps my greatest strength as an engineer is my network. I'm one person, there's no possible way I have all the context required to make decisions, and the higher leveled I became the more critical this skill became. In later sections I'll highlight how this grew, but for now this was the start of me building and working through my network, albeit at a minimal scope at this moment.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Senior Politician - Team to Organization Scope
&lt;/h2&gt;

&lt;p&gt;After you get beyond the brick wall before senior levels you'll find still more hurdles to overcome. This is the level where representation matters, delegation enters the conversation, and cross-team planning becomes a requirement to get progressively larger tasks done.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;By now I had cooled my head, learned to listen to others, but I had a whole new level of problem to contend with: I had to convince other people that something was a good idea to pursue.&lt;/p&gt;

&lt;p&gt;More often than not I would do so by informal conversations, convincing people to help with work outside of the scope of their teams roadmaps if not completely aside from it. I would try and circumvent the chain of command at a company for expediency on projects I happened to think were important.&lt;/p&gt;

&lt;p&gt;Needless to say this did not endear me to people outside of my team and organization as I represented a risk factor that could derail their roadmap by not considering the implications of the work I was trying to get people to do.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;Process, surprisingly, exists for a very good reason. That meant getting things roadmapped for other teams and learning negotiation skills when consulting with other team leads and managers, rather than taking advantage of engineers who didn't happen to know any better. Granted there's another message in there about volunteer culture and how that can dramatically backfire, but we'll get into that in a moment.&lt;/p&gt;

&lt;p&gt;No, for this section the growth areas were around learning to negotiate and get things on a roadmap, schedule the work, and then see it through rather than tossing something over the fence and hoping it magically showed up done on the other side.&lt;/p&gt;

&lt;p&gt;It meant having uncomfortable discussions and accepting when the answer was sometimes no, and working with that to reprioritize or in rare cases escalating to surface truly severe concerns. Sometimes, even then, the answer is still no and I had to learn how to work with that.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Strength
&lt;/h3&gt;

&lt;p&gt;Through this I had learned how to start negotiations, how to prepare formal documents and proposals, and how to make effective cases for what I believed should be done which led to a much higher rate of success and delivery.&lt;/p&gt;

&lt;p&gt;In some ways one could fairly say "give us a proposal" is code for "screw off, we're busy" and they may be right there, though I choose to take a sunnier view of that and say it's more likely to mean they need a full story of the scope of the request and the details behind it beyond a simple "X is a problem, we should fix that."&lt;/p&gt;

&lt;p&gt;It taught me to solidify context and details of problems into actionable items that could be delivered to others, rather than requiring my direct involvement to get things done. It was the start of me learning to delegate and break apart work, which is what got me to Staff levels.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Staff Politician - Organization to Company Scope
&lt;/h2&gt;

&lt;p&gt;Beyond Senior levels there's a much higher wall to climb to Staff levels, and that's because the lesson here is that it's no longer an individual contributor's job, it's a leader's job to work through an entire organization rather than trying to play solo hero any more.&lt;/p&gt;

&lt;p&gt;It's a hard lesson to learn, and I was no exception.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;You spend years building engineering intuition on how to solve a problem yourself. You could totally get it done in a few hours if they'd let you, they just don't understand how simple it actually is, they're overcomplicating things!&lt;/p&gt;

&lt;p&gt;Sufficient to say I was still fairly arrogant at this stage of my career. I believed I could solo tasks that were well beyond the realm of what any single engineer should ever attempt on their own. Not because I couldn't, no, but &lt;em&gt;because I shouldn't&lt;/em&gt;.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;&lt;em&gt;Shouldn't&lt;/em&gt; is a real loaded word there. What do I mean by that?&lt;/p&gt;

&lt;p&gt;If a problem is beyond the scope of a single engineer and can effect a whole organization and even the entire company there's no possible way that engineer has enough context to fully realize and deliver on that problem. To think otherwise is folly, and likely to lead to a lot of misses in delivery for not really understanding a domain and customer requirements.&lt;/p&gt;

&lt;p&gt;The solution, again, was listening and on a much grander scale. It meant having several meetings, message chains, documents, proposals, and more to make sure a domain was fully explored and qualified rather than making assumptions that could lead to failure.&lt;/p&gt;

&lt;p&gt;It meant no longer being an engineer, but being a representative for an entire organization of engineers that trust you to make wise decisions. Sometimes this can even reach a company scale at this level.&lt;/p&gt;

&lt;p&gt;It means that all the negotiation skills developed up to this point are now table stakes for any reasonably sized job.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Strength
&lt;/h3&gt;

&lt;p&gt;Through this I had also learned a critical skill that I had not quite realized. Delegating at that scale means that you can grow engineers effectively. It means that you can ensure people are connected that can help each other grow, that you can give tasks that address weaknesses, and that you can create examples of competencies that can be leveraged in promotions.&lt;/p&gt;

&lt;p&gt;At this stage I started to realize the ability to level up an entire organization around me, and start to establish networks of experts not only in the company, but in the entire industry.&lt;/p&gt;

&lt;p&gt;It was the beginning of me starting to actually lead, and hopefully do so wisely as a representative of both my team and organization.&lt;/p&gt;

&lt;h2&gt;
  
  
  The Principal Politician - Company to Industry Scope
&lt;/h2&gt;

&lt;p&gt;After all of this I find myself at a new stage, that of a Principal Engineer, that is still beyond my full understanding. Really Staff in many cases may still be.&lt;/p&gt;

&lt;p&gt;At this level any decision you make can rock an entire company, if not the entire industry around you, and because of that it requires exceptional wisdom, patience, and listening to succeed in.&lt;/p&gt;

&lt;p&gt;Unfortunately I only have two of those on a good day, and which two those are depends on the problem at hand.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Problem
&lt;/h3&gt;

&lt;p&gt;By now you're not only a representative for your organization, but for the entire company if not the entire industry.  To say that that requires a deft and steady hand is an exceptional understatement.&lt;/p&gt;

&lt;p&gt;The cost of failure becomes exceptionally high, even terrifying to the point of stagnation and avoidance of unfamiliar territory. It can mean becoming stuck in your ways and refusing to change, returning and harkening to some of the arrogance from previous stages.&lt;/p&gt;

&lt;p&gt;The problem now is that you have enough experience to back that up, and using it irresponsibly can do immeasurable damage to a company and its engineers. Being the representative of an entire company is a significant responsibility.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Solution
&lt;/h3&gt;

&lt;p&gt;Fail. Fail often, fail fast, and be willing to make mistakes.&lt;/p&gt;

&lt;p&gt;Of course this sounds patently absurd, who would recommend failing as a solution?&lt;/p&gt;

&lt;p&gt;The trick here is to fail in such a way that you've made it cheap, easy, and fast to recover and shift positions. It allows you to take much larger risks safely and qualify risks that may otherwise be unknown through formal proposal and discussion.&lt;/p&gt;

&lt;p&gt;Even the best decisions and most well thought out proposals will inevitably have failure modes. It's impossible to get everything right, so optimizing for such can be foolish and costly, as it presumes a perfection which will never exist.&lt;/p&gt;

&lt;p&gt;Amusingly even if you &lt;em&gt;could&lt;/em&gt; get something perfect it would still be wrong because software is by nature a moving target. Demands change, needs shift, customers cycle, and no one person can reliably predict the future. Through maturity though they can certainly make some educated guesses.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Strength
&lt;/h3&gt;

&lt;p&gt;By being willing to fail and consider the risks taken one starts to develop skills of tactical investments and being able to delegate entire organizations to pursue promising potentials and qualify whether or not they pan out.&lt;/p&gt;

&lt;p&gt;It develops a far more robust model of software where teams are safe to make mistakes, to grow and learn at a much larger scale, and start to produce more Staff level competencies and perhaps beyond. When failure is untethered from shame it allows for growth and transparency at a company scale, and a much healthier engineering culture will emerge from it.&lt;/p&gt;

&lt;p&gt;In conjunction with the other strengths an engineer executing at this level can do some incredible things.&lt;/p&gt;

&lt;p&gt;Truthfully these are still lessons I am learning, and will continue to learn over the next few years as I mature into this level myself.&lt;/p&gt;

&lt;h2&gt;
  
  
  Closing Thoughts
&lt;/h2&gt;

&lt;p&gt;Politics take different shapes at every stage, but the truth of the matter is that there needs to be a healthy relationship with expectations at every level for there to be safety to grow in them. Some companies naturally will be exceptionally hostile here with top-down mandates while others will have no structure and let people do as they will. Both have their failure modes and create very different political climates to work in.&lt;/p&gt;

&lt;p&gt;In many ways I am still ever much the fool in regards to political nuance at work, but I have certainly grown from where I was in the past, and can see ways I can continue to improve myself in the future.&lt;/p&gt;

&lt;p&gt;One step at a time, we grow every day, and you're just as capable of that growth yourself.&lt;/p&gt;

&lt;p&gt;So go out, experiment, fail, and above all?&lt;/p&gt;

&lt;p&gt;&lt;em&gt;LISTEN&lt;/em&gt;&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>politics</category>
      <category>career</category>
    </item>
    <item>
      <title>Tales of the Autistic Developer – Order and Chaos</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Fri, 19 Nov 2021 10:05:15 +0000</pubDate>
      <link>https://dev.to/baweaver/tales-of-the-autistic-developer-order-and-chaos-2o0p</link>
      <guid>https://dev.to/baweaver/tales-of-the-autistic-developer-order-and-chaos-2o0p</guid>
      <description>&lt;p&gt;For those who don't know me, I'm autistic. I've been a developer for the better part of a decade.&lt;/p&gt;

&lt;p&gt;I didn't find out I was ASD until 19, and didn't reconcile with that until years later. These posts will be a combination of advice I've given to those who are like me, as well as a letter of sorts to my past self who could have used a lot of it.&lt;/p&gt;

&lt;p&gt;I write these posts in the hopes that someone like me will find value in knowing a very simple and very important truth about ASD:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You are not alone, and you are loved.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Order and Chaos
&lt;/h2&gt;

&lt;p&gt;While I am most certainly autistic, I'm also ADHD, making for a very interesting mix of traits. My mind, quite simply, operates in a mode of constant chaos.&lt;/p&gt;

&lt;p&gt;It bounces from idea to idea as fast as something catches its fancy, and trying to tame it into some semblance of productivity has been my life's work.&lt;/p&gt;

&lt;p&gt;The irony then is that my entire existence is implementing systems of order by which to counteract that natural state of chaos, but the deeper irony? Both have become indispensable to my work, and how I think.&lt;/p&gt;

&lt;h3&gt;
  
  
  A State of Chaos
&lt;/h3&gt;

&lt;p&gt;In my decade or more of experience in the industry I've come to a very simple truth:&lt;/p&gt;

&lt;p&gt;The hardest problems in technology are organizational, rather than technological.&lt;/p&gt;

&lt;p&gt;While solutions may certainly exist, discovering them, building consensus, and orchestrating the release ends up being an exercise in chaos more often than not. There are entire categories of problems that are well beyond the scope of a single engineer, and quite frankly should be despite the best efforts of some to do otherwise.&lt;/p&gt;

&lt;p&gt;The larger the problem the larger the surrounding context it involves, and by extension the more people will need to be involved to solve it properly. Bypassing this means bypassing critical context and insight, and potentially making very grave mistakes in the solutions you create.&lt;/p&gt;

&lt;p&gt;Simply put that's the critical gap between a Senior and a Staff engineer, but that's a story for another day.&lt;/p&gt;

&lt;p&gt;The point of this is that without a plan and systems of communication, organization, networking, and other methods of managing all that context you end up with chaos. A ship without a rudder sailing aimlessly into the distance.&lt;/p&gt;

&lt;p&gt;That might work well for the short term, but direction becomes critical if you want to do anything beyond floating in a loosely forward direction.&lt;/p&gt;

&lt;p&gt;Now this all brings up a very interesting question: how does someone with Autism / ADHD, both conditions known for not being great at all of the above, manage to survive past those levels?&lt;/p&gt;

&lt;h3&gt;
  
  
  A Contradictory Existence
&lt;/h3&gt;

&lt;p&gt;As someone with Autism I like things to make sense, to have a natural order, and to fall into the right place. My life is dominated in many ways by a desire for order and rigor. Take me to any restaurant and I guarantee I'll order the same thing every time, and most of the owners will know me by name if I've lived somewhere for any decent amount of time. Consistency brings me peace of mind, and helps me to focus.&lt;/p&gt;

&lt;p&gt;You can imagine that 2020 and 2021 were not kind on that note, but again, a story for another day.&lt;/p&gt;

&lt;p&gt;Contradictorily and very ironically being ADHD means that my mind works in a state of disorder. I bounce between 10 ideas at any given time, find new hobbies everywhere, and can't focus to save my life.&lt;/p&gt;

&lt;p&gt;These two traits are at constant odds with each other in my head. In many cases it feels like I humor myself between the two of them depending on which trait dominates on a given day. Do I need to snap out of an obsession from my Autistic nature, or do I need to drill down and focus on one task and quit being capricious from my ADHD nature?&lt;/p&gt;

&lt;h3&gt;
  
  
  Systems of Order
&lt;/h3&gt;

&lt;p&gt;The answer is that I use them both against each other, where one is weak I supplement the other's strength. I create systems of order in which I can succeed with ADHD, via calendars, notes, reminders, and anything else I can get a hold of to keep myself accountable.&lt;/p&gt;

&lt;p&gt;I have collections of notes spanning many years capturing insights, networks, communications, and more to make sure I can find the right people when I need to to get critical context. I create systems by which to capture and distill that information into useful documents, and further methods to distill that information into actionable content and executive summaries to inform those above me on a path forward.&lt;/p&gt;

&lt;p&gt;The simple truth is I do not trust myself to be responsible, so any system of order I make is explicitly to keep myself accountable to a task. Being autistic I find great comfort in order and certainty, in rote and repetition of tasks, which means I'm very good at creating order of chaos.&lt;/p&gt;

&lt;p&gt;What's interesting about that statement is the reverse: To get good at creating order of chaos, one has to be able to live in chaos and thrive in it first. ADHD's lack of a clear focal point and its tendency for capriciousness benefits me in that I'm far more comfortable with disorder and chaos than many without it. After all, my head works like that, even if I do like order more.&lt;/p&gt;

&lt;p&gt;The critical point is that I can recognize chaos for what it is, and in doing so start to implement systems of order on top of it to facilitate progress. The larger the chaos the more this ability shines, but there are certainly dangers in forms of chaos that I cannot comprehend nor manage, so knowing my limit is critical in stepping back and consulting others first.&lt;/p&gt;

&lt;p&gt;What's more interesting is that these systems of order allow something else entirely.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Cost of Freedom
&lt;/h3&gt;

&lt;p&gt;Through systems of order balancing chaos, I'm allowed a certain freedom of execution. I've created a solid foundation in which I can experiment, do as I will, and explore beyond scopes I may have been able to more early in my career.&lt;/p&gt;

&lt;p&gt;When I was much younger I did not have such systems of order, yet I yearned for freedom. Freedom to play, to explore, to do what I wanted to do. Many times, when given such freedom, it would be my undoing. If anything seeking freedom was what about got me fired in a few roles in the past, as I did not have nearly the support structure I needed to execute upon it.&lt;/p&gt;

&lt;p&gt;By creating systems of order that can sustain me, and networks by which I can execute through, I'm able to create greater freedoms by which myself and others can pursue tasks as we wish.&lt;/p&gt;

&lt;p&gt;The irony, and the cost of that freedom, are systems of organization to prevent chaos beyond our ability to manage from eroding our foundation and putting us in positions where tasks are quite literally impossible to achieve.&lt;/p&gt;

&lt;p&gt;I know, I've put myself in that position several times before, and it's not fun.&lt;/p&gt;

&lt;p&gt;That said, it was probably those very experiences that gave me the critical insight that there's a high cost to freedom, and the higher one goes and the wider scope that one executes at that cost grows with it.&lt;/p&gt;

&lt;p&gt;Consider a manager who creates systems of organization through Jira or Agile methodologies (it could be anything though, those are just examples). Through that newer engineers can execute tasks to move the team forward, but inside that framework they have the freedom to add tasks and propose new solutions, all because the team is still moving forward due to the manager's planning.&lt;/p&gt;

&lt;p&gt;That manager shields the team from chaos beyond their scope of view, and in doing so gives them the freedom to execute in their own scope. Of course as team members level up they'll become privy to far more of the chaos the team is wrapped up in, but preferably only when they're ready to face it.&lt;/p&gt;

&lt;p&gt;Extrapolate this to directors, department heads, GMs, VPs, C-levels, and more and you can see that the costs of organizing at each progressive level grow exponentially, but the freedom and clarity they provide by doing so to those under them grows with it.&lt;/p&gt;

&lt;p&gt;That's a pretty amazing power, and one I hope to have one day, but one I have a lot of work to do to get to.&lt;/p&gt;

&lt;h3&gt;
  
  
  Superpower or Curse?
&lt;/h3&gt;

&lt;p&gt;I exist in a world somewhere between chaos and order, creating order of chaos, and living a life that allows me to survive chaos perhaps beyond what would otherwise be normal. While this may sound like some form of superpower, it's far more a precarious balancing act, and if I happen to slip and let one side dominate it does not end well for me.&lt;/p&gt;

&lt;p&gt;Should I let my Autistic nature dominate, I'll begin to lock down and go back to the familiar. Anything outside of that box won't happen, and I'll likely be like that for a week or two while I regain my composure. I start to jettison anything and everything not necessary to finish existing commitments, and will very much be in a state of Autistic burnout. Recovery from that is painful, and frequently I try and take a vacation when I find myself flirting too much with that line.&lt;/p&gt;

&lt;p&gt;Should I let my ADHD nature dominate I'll get nothing done. I'll be on an endorphin hunt looking for anything and everything that can give me just a bit of a rush. Whether that be shopping, smells, foods, experiences, new comics, books, games, or any of the above I want something to make me feel whole and "happy" again, despite that being impossible. ADHD burnout means that I'll be on a perpetual hunt for a new high, until I detox my mind and get back to a normal state.&lt;/p&gt;

&lt;p&gt;If you know me personally you'll notice that I have routines, whether that be coffee or food, that I tend to adhere to to satisfy my Autistic nature. You'll also notice the tendency of me pursuing new and novel hobbies on occasion, but in very limited quantities, to satisfy my ADHD nature.&lt;/p&gt;

&lt;p&gt;I can't ignore them, but neither can I let them win and dominate my life, which brings up the question if this is a superpower or a curse.&lt;/p&gt;

&lt;p&gt;Really though? It depends on the day.&lt;/p&gt;

&lt;h3&gt;
  
  
  Closing Thoughts
&lt;/h3&gt;

&lt;p&gt;As I grow in my career my permanent fear is that I encounter chaos beyond my capacity requiring order that tips me beyond my limits. Thankfully I've had the support of many wise friends, mentors, elders, and family to guide me through those times. People who have been there, and seen the tops of the mountains I'm climbing, and that's made all the difference in the world. To even know it's possible, and that my ideals aren't wrong, is more valuable than gold to me.&lt;/p&gt;

&lt;p&gt;If there's one final lesson I could impart from this article it's that you're not in this alone, not now and not ever. There will be things beyond us, but there will also be people there with an outstretched hand if you look for them.&lt;/p&gt;

&lt;p&gt;We are not alone, not in the greatest chaos, nor in the most thorough systems of order we could imagine. Alone we will fail, but together we can achieve so much more, and that's a lesson I wish I had learned much earlier in my life.&lt;/p&gt;

</description>
      <category>mentalhealth</category>
      <category>autism</category>
      <category>adhd</category>
    </item>
    <item>
      <title>Future of Ruby – AST Tooling</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Sun, 14 Nov 2021 08:22:39 +0000</pubDate>
      <link>https://dev.to/baweaver/future-of-ruby-ast-tooling-9i1</link>
      <guid>https://dev.to/baweaver/future-of-ruby-ast-tooling-9i1</guid>
      <description>&lt;p&gt;This is a series meant to explore the potential future of the Ruby programming language by visiting current technologies and ideas around them, and how those might apply to the future. In this series you'll find some tools which can be used today, some which may be used tomorrow, and a collection of aspirations of what could be.&lt;/p&gt;

&lt;p&gt;As this is a look into a potential future, you may or may not see these things come to pass, and that's ok. This is not meant to be prescriptive, but to start conversations on what things could be.&lt;/p&gt;

&lt;p&gt;With that being said, let's take a look into the potential future of Ruby.&lt;/p&gt;

&lt;h2&gt;
  
  
  AST Tooling
&lt;/h2&gt;

&lt;p&gt;Programs are, at their core, text with special semantic meaning. Using Regex we can certainly treat Ruby as just plain text, but in doing so we lose the semantic meaning of what makes Ruby Ruby.&lt;/p&gt;

&lt;p&gt;Enter in ASTs, or Abstract Syntax Trees. ASTs are a data structure that represents a Ruby program as a series of nested nodes, broken into relevant pieces using knowledge of the language.&lt;/p&gt;

&lt;p&gt;Ruby has a few different implementations of this, the core implementation being Ripper:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="no"&gt;Ripper&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sexp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'def hello(world) "Hello, #{world}!"; end'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# [:program,&lt;/span&gt;
&lt;span class="c1"&gt;#   [[:def,&lt;/span&gt;
&lt;span class="c1"&gt;#     [:@ident, "hello", [1, 4]],&lt;/span&gt;
&lt;span class="c1"&gt;#     [:paren,&lt;/span&gt;
&lt;span class="c1"&gt;#      [:params, [[:@ident, "world", [1, 10]]], nil, nil, nil, nil, nil, nil]],&lt;/span&gt;
&lt;span class="c1"&gt;#     [:bodystmt,&lt;/span&gt;
&lt;span class="c1"&gt;#      [[:string_literal,&lt;/span&gt;
&lt;span class="c1"&gt;#        [:string_content,&lt;/span&gt;
&lt;span class="c1"&gt;#         [:@tstring_content, "Hello, ", [1, 18]],&lt;/span&gt;
&lt;span class="c1"&gt;#         [:string_embexpr, [[:var_ref, [:@ident, "world", [1, 27]]]]],&lt;/span&gt;
&lt;span class="c1"&gt;#         [:@tstring_content, "!", [1, 33]]]]],&lt;/span&gt;
&lt;span class="c1"&gt;#      nil,&lt;/span&gt;
&lt;span class="c1"&gt;#      nil,&lt;/span&gt;
&lt;span class="c1"&gt;#      nil]]]]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The AST is represented as a series of nested arrays. The problem with this, of course, is that it can be difficult to work on programmatically for tooling developers.&lt;/p&gt;

&lt;p&gt;Enter the Whitequark parser, which you can experiment with &lt;a href="https://nodepattern.herokuapp.com/"&gt;here&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;ruby_code&lt;/span&gt;  &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'def hello(world) "Hello, #{world}!"; end'&lt;/span&gt;
&lt;span class="n"&gt;expression&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Parser&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CurrentRuby&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ruby_code&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# s(:def, :hello,&lt;/span&gt;
&lt;span class="c1"&gt;#   s(:args,&lt;/span&gt;
&lt;span class="c1"&gt;#     s(:arg, :world)),&lt;/span&gt;
&lt;span class="c1"&gt;#   s(:dstr,&lt;/span&gt;
&lt;span class="c1"&gt;#     s(:str, "Hello, "),&lt;/span&gt;
&lt;span class="c1"&gt;#     s(:begin,&lt;/span&gt;
&lt;span class="c1"&gt;#       s(:lvar, :world)),&lt;/span&gt;
&lt;span class="c1"&gt;#     s(:str, "!")))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are a few others like Melbourne, JRubyParser, and ruby_parser but we'll focus on the Whitequark parser for the sake of this article.&lt;/p&gt;

&lt;p&gt;Put simply, I believe that it's more accessible and easily usable than Ripper, and will be the base of a lot of what could be the future of Ruby tooling. That's what we're going to explore today.&lt;/p&gt;

&lt;p&gt;We'll be covering the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;strong&gt;Find and Replace&lt;/strong&gt; - Regex and literal F&amp;amp;R is limited and prone to accidental replacements. Can we be more precise?&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;EmberJS Style Codemods&lt;/strong&gt; - EmberJS uses Codemods to upgrade itself, and ships with them every major version. Think that, but Rails or other major Ruby gems.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Babel Transpilation&lt;/strong&gt; - JS evolves so quickly because you can fairly easily try out experimental syntax via Babel and get proofs-of-concept out fast.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;A to B Inferred Transforms&lt;/strong&gt; - Given code "A" find the transformations necessary to get to code "B".&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Macros&lt;/strong&gt; - The Whitequark parser has a dual, Unparser. If Parser was standard Ruby, and any live code could be turned into an AST, we could rearrange it for some dramatic effects.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Now that's a lot of ground to cover, so shall we get started?&lt;/p&gt;

&lt;h3&gt;
  
  
  Find and Replace
&lt;/h3&gt;

&lt;p&gt;Let's say you wanted to replace every instance of a certain piece of text in your program with another one. Most editors have a find and replace function with added regex support which can be very handy.&lt;/p&gt;

&lt;p&gt;For this example let's say you decided that you had named a variable &lt;code&gt;hash&lt;/code&gt; and want to replace it with something more descriptive, such as &lt;code&gt;person&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;HTTP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;get&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'some_site/people/1.json'&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;then&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;JSON&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; was found!"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure, it'd work for this case, but say that right below that code was something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is currently &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;A global find and replace would be a real bad idea in this case, changing the meaning of your program. This is because the text "hash" has no semantic meaning, but a node related to "hash" definitely does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# HEREDOCs surrounded in single-quotes prevents interpolation, which&lt;/span&gt;
&lt;span class="c1"&gt;# we need here.&lt;/span&gt;
&lt;span class="no"&gt;Parser&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CurrentRuby&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;~&lt;/span&gt;&lt;span class="no"&gt;'RUBY'&lt;/span&gt;&lt;span class="sh"&gt;
  hash = HTTP.get('some_site/people/1.json').then { JSON.parse(_1) }
  puts "&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'name'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt; was found!"
  puts "&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt; is currently &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;test_object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;hash&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="sh"&gt;"
&lt;/span&gt;&lt;span class="no"&gt;RUBY&lt;/span&gt;

&lt;span class="c1"&gt;# This generates the following AST:&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:begin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:lvasgn&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:hash&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:numblock&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:HTTP&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:get&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"some_site/people/1.json"&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt; &lt;span class="ss"&gt;:then&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:const&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:JSON&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:parse&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:lvar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:_1&lt;/span&gt;&lt;span class="p"&gt;)))),&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:puts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:dstr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:begin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:lvar&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:hash&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:[]&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"name"&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt;
      &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;" was found!"&lt;/span&gt;&lt;span class="p"&gt;))),&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:puts&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
    &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:dstr&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
      &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:begin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:test_object&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;)),&lt;/span&gt;
      &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;" is currently "&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
      &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:begin&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
        &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
          &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:send&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:test_object&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;:hash&lt;/span&gt;&lt;span class="p"&gt;)))))&lt;/span&gt;

&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we have &lt;code&gt;hash&lt;/code&gt; referring to a node of type &lt;code&gt;:lvasgn&lt;/code&gt; (local variable assign) and &lt;code&gt;:lvar&lt;/code&gt; (local variable) as opposed to the later node &lt;code&gt;s(:send, s(:send, nil, :test_object), :hash)))&lt;/code&gt; which relates to the &lt;code&gt;hash&lt;/code&gt; method being called on the &lt;code&gt;test_object&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;ASTs gave distinct meaning to each part of that text, and given that we could more easily do replacements in a much more descriptive way. Think of it, in a way, like static typing for manipulating a program and ensuring your intent is more clearly expressed and executed.&lt;/p&gt;

&lt;p&gt;Editors currently have regex support, but who's to say that we couldn't have AST or NodePattern support in the future?&lt;/p&gt;

&lt;p&gt;Using &lt;a href="https://nodepattern.herokuapp.com/"&gt;MarcAndre's NodePattern tool&lt;/a&gt; we can even use a regular language designed for ASTs known as NodePattern to find any local variable or assignment related to &lt;code&gt;hash&lt;/code&gt; (borrowing some from &lt;a href="https://github.com/marcandre/np/blob/4f45f184d7f4c147e1efe60d7a0fe51aa446ab11/lib/np/debugger.rb#L4"&gt;src&lt;/a&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"rubocop"&lt;/span&gt;
&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s2"&gt;"parser/current"&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ruby_parser&lt;/span&gt;
  &lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;RuboCop&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;AST&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Parser&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;CurrentRuby&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;diagnostics&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all_errors_are_fatal&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="n"&gt;parser&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;ast_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;buffer&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Parser&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Source&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;Buffer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'(ruby)'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;source: &lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;ruby_parser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;parse&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;buffer&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;node_pattern&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;RuboCop&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;NodePattern&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;hash_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node_pattern&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;~&lt;/span&gt;&lt;span class="no"&gt;NODE&lt;/span&gt;&lt;span class="sh"&gt;
  { # OR pattern
    ({lvasgn lvar} :hash _) # Either a local var or assignment
    (send nil? :hash)       # ...or a call to that variable
  } # End OR pattern
&lt;/span&gt;&lt;span class="no"&gt;NODE&lt;/span&gt;

&lt;span class="n"&gt;hash_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ast_of&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"hash = {}"&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In fact this is how RuboCop autocorrect works by searching for a certain node and doing something when it's found.&lt;/p&gt;

&lt;p&gt;Some of these tools have even already been wrapped, like &lt;a href="https://github.com/jonatas/fast"&gt;Jonatas's work on FFast&lt;/a&gt; which works on top of NodePattern and some of RuboCop's previous work. Really the only things between us and this future is a bit more wrapping and polish, as well as integrations into something like VSCode.&lt;/p&gt;

&lt;p&gt;Any takers? I may well wrap some of this in a more minimalist gem that provides an easier-to-use interface to build on, as the current parts are non-intuitive unless you're willing to dig into the code on a non-trivial basis.&lt;/p&gt;

&lt;h3&gt;
  
  
  EmberJS Style Codemods
&lt;/h3&gt;

&lt;p&gt;There are a lot, and I mean a lot, of ideas we can and should be taking from Javascript in the Ruby community. One of them is the idea of code mods for migrating syntaxes, and &lt;em&gt;especially&lt;/em&gt; for upgrades from old versions.&lt;/p&gt;

&lt;p&gt;When I was working with EmberJS there were &lt;a href="https://github.com/ember-codemods"&gt;multiple codemods&lt;/a&gt; designed to make migrating from one version to the next, and it was a very pleasant experience. The idea was that after you upgraded dependencies you ran one command and most if not all of the upgrade was done for your syntax.&lt;/p&gt;

&lt;p&gt;Why can't we have that in Ruby? Why not especially for Rails? Turns out the answer is that there are indeed some of these things already:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://docs.rubocop.org/rubocop-rails/cops_rails.html"&gt;https://docs.rubocop.org/rubocop-rails/cops_rails.html&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;Notice that several of those support "autocorrection", meaning that running RuboCop with &lt;code&gt;-a&lt;/code&gt; will fix them for you:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight shell"&gt;&lt;code&gt;rubocop &lt;span class="nt"&gt;-a&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Let's take a glance at the &lt;code&gt;action_filter&lt;/code&gt; cop real quick &lt;a href="https://github.com/rubocop/rubocop-rails/blob/master/lib/rubocop/cop/rails/action_filter.rb"&gt;here&lt;/a&gt;, but just a quick part of it:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;check_method_node&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;method_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method_name&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;bad_methods&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;format&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;MSG&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;prefer: &lt;/span&gt;&lt;span class="n"&gt;preferred_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="ss"&gt;current: &lt;/span&gt;&lt;span class="n"&gt;method_name&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="n"&gt;add_offense&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;corrector&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;corrector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;replace&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;preferred_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;node&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;loc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;selector&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;source&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice that after &lt;code&gt;add_offense&lt;/code&gt; it uses &lt;code&gt;corrector.replace&lt;/code&gt; to replace with a preferred method source. Not only that, but if we went over to the &lt;a href="https://github.com/rubocop/rubocop-rails/blob/master/spec/rubocop/cop/rails/action_filter_spec.rb"&gt;specs&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;described_class&lt;/span&gt;&lt;span class="o"&gt;::&lt;/span&gt;&lt;span class="no"&gt;FILTER_METHODS&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;it&lt;/span&gt; &lt;span class="s2"&gt;"registers an offense for &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
    &lt;span class="n"&gt;offenses&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;inspect_source&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; :name"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;expect&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;offenses&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;to&lt;/span&gt; &lt;span class="n"&gt;eq&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...we can see that there are even tests for it, meaning that we can not only describe and implement transformations, but programmatically test them so we don't have to manually rerun them on our entire codebases.&lt;/p&gt;

&lt;p&gt;That's a lot of power. Imagine with me that new versions of Rails were bundled with autocorrectors which got people 90%+ done with a Rails upgrade, just from running one more command or potentially even bundling it in the official Rails upgrade process itself.&lt;/p&gt;

&lt;p&gt;We could dramatically reduce the potential for manual errors, and make upgrading a substantially more seamless and painless process.&lt;/p&gt;

&lt;p&gt;The secret here is that I do not believe this is far off, and there may well be people already doing this on the Rails core team.&lt;/p&gt;

&lt;h3&gt;
  
  
  Babel Transpiler
&lt;/h3&gt;

&lt;p&gt;Another lesson we can and should take from Javascript is the Babel traspiler. Babel allows for the introduction of syntax before it's officially in the language, making it extremely effective for testing and experimentation of new language features. Proof-of-concepts can be more easily verified, and frequently TC-39 uses them in formal proposals.&lt;/p&gt;

&lt;p&gt;Not only that, but the language can polyfill older versions with new features and enhancements, allowing developers to use features only present in newer versions more easily. For Javascript that's a huge deal as they have to deal with such variance in web browser support.&lt;/p&gt;

&lt;p&gt;As it would happen, the folks behind &lt;a href="https://github.com/ruby-next/ruby-next"&gt;Ruby Next&lt;/a&gt; have some ideas here, and have done a significant amount of work in enabling this very vision to become a reality.&lt;/p&gt;

&lt;p&gt;They wrote quite a bit on that very topic here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://evilmartians.com/chronicles/ruby-next-make-all-rubies-quack-alike"&gt;https://evilmartians.com/chronicles/ruby-next-make-all-rubies-quack-alike&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;...and a lot of those terms are going to look very familiar to what you've been reading already, and there's a &lt;em&gt;very&lt;/em&gt; good reason for that.&lt;/p&gt;

&lt;h3&gt;
  
  
  A to B Inferred Transforms
&lt;/h3&gt;

&lt;p&gt;Perhaps the most troublesome part of writing regex, and really any regular language, is getting the syntax right. The same is true of NodePatterns. Why can't we just say that we have code "A" here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;even?&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and have it figure out the syntax to go to code "B" here?:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:even?&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For us as humans that seems pretty straightforward. If the block argument matches the body, and only one operation is happening directly on it, we can replace that with the shorthand block syntax.&lt;/p&gt;

&lt;p&gt;What if we had a way to give code "A" and "B" and have Ruby find the transformations between the two?&lt;/p&gt;

&lt;p&gt;For simple cases that algorithm might look like this:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;Match the original syntax&lt;/li&gt;
&lt;li&gt;Find similarities with the desired target syntax&lt;/li&gt;
&lt;li&gt;Find what has changed&lt;/li&gt;
&lt;li&gt;Identify which parts of the code moved where&lt;/li&gt;
&lt;li&gt;Create matchers to capture moved parts in the original code&lt;/li&gt;
&lt;li&gt;Create code to generate the target code&lt;/li&gt;
&lt;li&gt;Profit&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;...but those are tree algorithms which are unfortunately beyond me at the moment. The implications, however, are staggering if this is pulled off. Having a meta-language that allows one to quickly generate code migration syntax would lower the barrier to entry of code migrations that can be bundled with upgrades, and also allow whole new methods of refactoring.&lt;/p&gt;

&lt;p&gt;Perhaps I'll experiment with this more later, but at the moment it is most certainly beyond my skills. I would venture a guess that algorithms used to solve word ladders, or perhaps levenshtein/word distances, could be used here though.&lt;/p&gt;

&lt;h3&gt;
  
  
  Macros
&lt;/h3&gt;

&lt;p&gt;Having a method to express A to B is great even in static files, but what if such things could be done in a running program?&lt;/p&gt;

&lt;p&gt;If ASTs were accessible in running Ruby programs, we could potentially create syntax which could rewrite syntax.&lt;/p&gt;

&lt;p&gt;Now if you're not familiar with the idea of macros from Crystal or LISP-like languages, you might wonder why you might care. One of the primary advantages is unfolding loops, allowing algorithms to go from &lt;code&gt;O(n^2)&lt;/code&gt; to &lt;code&gt;O(n)&lt;/code&gt;, meaning massive performance benefits.&lt;/p&gt;

&lt;p&gt;I'd written on this some time ago with &lt;code&gt;matchable&lt;/code&gt;:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://dev.to/baweaver/matchable-class-level-pattern-matching-macros-explained-32df"&gt;https://dev.to/baweaver/matchable-class-level-pattern-matching-macros-explained-32df&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;The particularly relevant part is replacing the idea of &lt;code&gt;public_send&lt;/code&gt; with a directly inlined code-path:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;valid_keys&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;deconstructed_values&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;deconstructed_values&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...as &lt;code&gt;public_send&lt;/code&gt; is slow compared to directly calling a method. If taken to logical extremes one could not only inline the actual method call, but extract the method code and interpolate it directly into such a method.&lt;/p&gt;

&lt;p&gt;There are already some techniques capable of doing just this, by combining Parser with &lt;a href="https://github.com/mbj/unparser"&gt;Unparser&lt;/a&gt;, but of course such things can only be done on Ruby files read in rather than in a REPL session which is where a lot more fun could happen.&lt;/p&gt;

&lt;p&gt;A live AST could really make a very interesting future here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;Now you might have noticed something particularly interesting with this article: Almost all of these items are either not that far off, or are already being used in production by several major players in the Ruby ecosystem.&lt;/p&gt;

&lt;p&gt;The truth is the future has already been coming, and perhaps our issues are not as much around tooling, but in making the tooling more accessible and well understood to our community.&lt;/p&gt;

&lt;p&gt;If this is combined with more official support from the Ruby core team, especially around the Whitequark and RuboCop parsers, I believe we'll take a great step forward. The challenge now is documentation, education, advocacy, and support.&lt;/p&gt;

&lt;p&gt;I believe all of those are very possible.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Let's Read – Eloquent Ruby – Ch 6</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Tue, 02 Nov 2021 06:30:06 +0000</pubDate>
      <link>https://dev.to/baweaver/lets-read-eloquent-ruby-ch-6-3eom</link>
      <guid>https://dev.to/baweaver/lets-read-eloquent-ruby-ch-6-3eom</guid>
      <description>&lt;p&gt;Perhaps my personal favorite recommendation for learning to program Ruby like a Rubyist, &lt;a href="http://eloquentruby.com/"&gt;Eloquent Ruby&lt;/a&gt; is a book I recommend frequently to this day. That said, it was released in 2011 and things have changed a bit since then.&lt;/p&gt;

&lt;p&gt;This series will focus on reading over Eloquent Ruby, noting things that may have changed or been updated since 2011 (around Ruby 1.9.2) to today (2021 — Ruby 3.0.x).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is an updated version of a previous unfinished Medium series of mine you can &lt;a href="https://medium.com/@baweaver/lets-read-eloquent-ruby-ch-1-b2115d1416a6"&gt;find here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Chapter 6. Use Symbols to Stand for Something
&lt;/h2&gt;

&lt;p&gt;This chapter covers one of the admittedly more confusing aspects of Ruby, Symbols. Still a bit confused about them yourself? Nothing to feel bad about on that, it took me a while before it clicked, and I can't say it's the most intuitive part of the language.&lt;/p&gt;

&lt;p&gt;That said, we'll take a look at Russ's thoughts here in the book and add some new context that we've seen in later versions of Ruby that have further blurred the line, as well as some of the arguments on why Symbol and String will never be merged (and should not be).&lt;/p&gt;

&lt;p&gt;The simplest description, however, you could use is that Strings are text meant for a human, and Symbols are labels meant for your program.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Two Faces of Strings
&lt;/h3&gt;

&lt;p&gt;The book starts in with an example that it deliberately simplifies by saying Symbols are really just Strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;string&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"dog"&lt;/span&gt;
&lt;span class="n"&gt;symbol&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:dog&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In many senses and at first glance, as the book mentions, they're the same three characters referring to the same idea: a dog. In many cases in Ruby they could even be used interchangeably (though they shouldn't be), further confounding folks trying to understand what the differences are.&lt;/p&gt;

&lt;p&gt;Take these two (old) Rails examples the book mentions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:all&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;book&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"all"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Modern versions do this instead:&lt;/span&gt;
&lt;span class="n"&gt;books&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Book&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;all&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The point is as a human we can tell we mean the same thing, and that's an important thing to realize about Ruby: It legitimately tries to not be surprising. If you could reasonably think a method could take a String or a Symbol chances are it will:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;testing&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:testing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Method: main.testing() (irb):1&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"testing"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; #&amp;lt;Method: main.testing() (irb):1&amp;gt;&lt;/span&gt;
&lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:testing&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="nb"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"testing"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's certainly not the only time Ruby does this, but a good general rule is to use Symbols in these types of cases. We'll get into that more in a moment along with the book.&lt;/p&gt;

&lt;h3&gt;
  
  
  Not Quite a String
&lt;/h3&gt;

&lt;p&gt;The book then goes on to ask why we need both, and presents an answer: Strings hold data that we're processing.&lt;/p&gt;

&lt;p&gt;In the Rails example &lt;code&gt;Book.all&lt;/code&gt; would return several records with String data in them. Data that could be changed, read, or acted upon by humans.&lt;/p&gt;

&lt;p&gt;For Symbols in the (outdated) example of &lt;code&gt;Book.find(:all)&lt;/code&gt; we're using &lt;code&gt;:all&lt;/code&gt; as a flag for what records to retrieve, or in the case of &lt;code&gt;method&lt;/code&gt; which method in the program we're retrieving. Those Symbols stand for an idea, and serve as a named label for the concept.&lt;/p&gt;

&lt;p&gt;The book then mentions Symbols could also be thought of as a very pared down String. Symbols don't particularly need manipulation, so all the methods for transforming and working with Strings don't make sense in the context of labeling something internal to the program.&lt;/p&gt;

&lt;p&gt;Because of those assumptions Symbols can be optimized. Granted in more recent versions of Ruby with frozen Strings this difference is not nearly as pronounced.&lt;/p&gt;

&lt;h3&gt;
  
  
  Optimized to Stand for Something
&lt;/h3&gt;

&lt;p&gt;Next up the book gets into the optimization implications we'd started to mention. Strings are optimized for data processing, and symbols are optimized for equality checks.&lt;/p&gt;

&lt;p&gt;In its example we have a few variables assigned to Symbols:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:all&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="ss"&gt;:all&lt;/span&gt;

&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:object_id&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;#  =&amp;gt; [784988, 784988, 784988]&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;===&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;eql?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;equal?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They're all the exact same entity. The book then goes on to say that this isn't the case for Strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"all"&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"all"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That's not strictly true any more with the frozen string literal comment:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# frozen_string_literal: true&lt;/span&gt;

&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"all"&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"all"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but we'll leave that alone for now and get back to the book. In the case where this is not enabled both of these Strings are in fact different objects, whereas there can only ever be one instance of any given Symbol.&lt;/p&gt;

&lt;p&gt;Symbols are also immutable (Strings can be frozen, or use the &lt;code&gt;frozen_string_literal&lt;/code&gt; comment above). That's why they tend to be used for Hash keys.&lt;/p&gt;

&lt;p&gt;Hash implements a few things behind the scenes to make sure that mutated keys don't crash programs, and as the book mentions this is most certainly a patch against Strings being mutable and potentially causing issues.&lt;/p&gt;

&lt;h3&gt;
  
  
  In the Wild
&lt;/h3&gt;

&lt;p&gt;The book then goes on to mention that yes, they're confusing, and lists a few more examples.&lt;/p&gt;

&lt;p&gt;In one you can convert between the two using &lt;code&gt;to_sym&lt;/code&gt; and &lt;code&gt;to_s&lt;/code&gt;, and in a significant amount of Ruby methods they'll even do this behind the scenes if they think you might reasonably use them interchangeably. Does that make it correct? Perhaps not, but it's such a common issue that we're probably pretty far beyond that by now.&lt;/p&gt;

&lt;p&gt;In older versions of Ruby (older than 1.9) asking for the public methods of an object used to return a String Array, but now returns Symbols, so even Ruby itself has some issue keeping track. Then again 1.8 to 1.9 was a pretty big gap, whereas 1.9 to 2.0 and 2.7 to 3.0 were far more minor.&lt;/p&gt;

&lt;h3&gt;
  
  
  Staying Out of Trouble
&lt;/h3&gt;

&lt;p&gt;One of the most common issues is going to come back to Hashes using Symbol and String interchangeably. If you did, they would break. &lt;code&gt;person[:name]&lt;/code&gt; is not the same as &lt;code&gt;person["name"]&lt;/code&gt; unless you have a &lt;code&gt;HashWithIndifferentAccess&lt;/code&gt; from Rails which hacks around this.&lt;/p&gt;

&lt;p&gt;Personally, and there are going to be a number of people who consider this heretical, I believe that most Hash keys should be Strings unless that Hash is being used internal to the program. That said, enforcing semantic style that requires any type of human interpretation is perilous, so I would never try and make that happen.&lt;/p&gt;

&lt;p&gt;Some have even tried to add JS object style where &lt;code&gt;person.name&lt;/code&gt; is the same as &lt;code&gt;person[:name]&lt;/code&gt; or &lt;code&gt;person["name"]&lt;/code&gt; using &lt;code&gt;Hashie&lt;/code&gt;, but the author and several other Rubyists came to the conclusion that this wasn't a great idea.&lt;/p&gt;

&lt;p&gt;Schneems wrote on this years ago, and it would be a good article to read into:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.schneems.com/2014/12/15/hashie-considered-harmful.html"&gt;https://www.schneems.com/2014/12/15/hashie-considered-harmful.html&lt;/a&gt;&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;Symbols and Strings aren't getting merged. &lt;a href="https://bugs.ruby-lang.org/issues/7792"&gt;That ship has sailed many times&lt;/a&gt; and has been rejected every single time. You can read more into it, but by now it's one of those features for better or worse that's part of the language.&lt;/p&gt;

&lt;p&gt;Deprecating features is not easy, and there are a number of them even Matz has said he regrets adding. That said, knowing that when writing something requires insight beyond what any programmer can reasonably be expected to have, and years of development on the feature to prove the point.&lt;/p&gt;

&lt;p&gt;Compatibility and non-breaking changes are critically important to a programming community, and I believe Matz and crew have made the correct decision on this, even though I may protest on principal.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>books</category>
    </item>
    <item>
      <title>Let's Read – Eloquent Ruby – Ch 5</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Tue, 19 Oct 2021 09:29:36 +0000</pubDate>
      <link>https://dev.to/baweaver/lets-read-eloquent-ruby-ch-5-28k8</link>
      <guid>https://dev.to/baweaver/lets-read-eloquent-ruby-ch-5-28k8</guid>
      <description>&lt;p&gt;Perhaps my personal favorite recommendation for learning to program Ruby like a Rubyist, &lt;a href="http://eloquentruby.com/"&gt;Eloquent Ruby&lt;/a&gt; is a book I recommend frequently to this day. That said, it was released in 2011 and things have changed a bit since then.&lt;/p&gt;

&lt;p&gt;This series will focus on reading over Eloquent Ruby, noting things that may have changed or been updated since 2011 (around Ruby 1.9.2) to today (2021 — Ruby 3.0.x).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is an updated version of a previous unfinished Medium series of mine you can &lt;a href="https://medium.com/@baweaver/lets-read-eloquent-ruby-ch-1-b2115d1416a6"&gt;find here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Chapter 5. Find the Right String with Regular Expressions
&lt;/h2&gt;

&lt;p&gt;This chapter focuses on Regular Expressions, or Regex for short. It's one of the most powerful concepts in programming around text manipulation, but also probably one of the most confusing.&lt;/p&gt;

&lt;p&gt;If you haven't already heard of these two I would highly suggest using them while exploring Regex:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;a href="https://rubular.com/"&gt;Rubular&lt;/a&gt; - Basic Ruby-centric Regex tester&lt;/li&gt;
&lt;li&gt;
&lt;a href="https://regexr.com/"&gt;Regexr&lt;/a&gt; - More advanced, explains each segment of a Regex&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Personally I tend to use Rubular more, but mostly because the extra info Regexr presents is a bit too noisy for me. In either case I would highly suggest running examples from this chapter and experimenting with them in either tool.&lt;/p&gt;

&lt;p&gt;With that said, let's get into it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Introductory Examples
&lt;/h3&gt;

&lt;p&gt;The chapter opens with a few examples, like to start with why do you want Regex? The book uses the &lt;code&gt;String&lt;/code&gt; &lt;code&gt;"09:24 AM"&lt;/code&gt; as an example. How can you tell it's a time? AM or PM? 24H or 12H? Maybe even ambiguous. These are a lot of questions that can be a bit difficult to answer with just &lt;code&gt;String&lt;/code&gt; methods, requiring something a bit more powerful.&lt;/p&gt;

&lt;p&gt;Think of Regex like a method of describing the shape of text. &lt;code&gt;"09:24 AM"&lt;/code&gt; is composed of two digits, a colon, two digits, a space, and AM or PM. Regex is a language that lets us say exactly that:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Regex starts and ends with a `/`, or surrounded by %r{}&lt;/span&gt;
&lt;span class="n"&gt;time_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/\d{2}:\d{2} (AM|PM)/&lt;/span&gt;
&lt;span class="c1"&gt;# time_match = %r{\d{2}:\d{2} (AM|PM)}&lt;/span&gt;

&lt;span class="n"&gt;time_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"09:24 AM"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that's all a bit dense to start out with, so let's step back along with the book to get into a few more examples.&lt;/p&gt;

&lt;h3&gt;
  
  
  Matching One Character at a Time
&lt;/h3&gt;

&lt;p&gt;The book lists a few examples, but let's turn those into code real quick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The regular expression x will match x.&lt;/span&gt;
&lt;span class="sr"&gt;/x/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"x"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# The regular expression aaa will match three a’s all in a row.&lt;/span&gt;
&lt;span class="sr"&gt;/aaa/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"aaa"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# The regular expression 123 will match the first three numbers.&lt;/span&gt;
&lt;span class="sr"&gt;/123/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"123"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# The regular expression R2D2 will match the name of a certain sci-fi robot.&lt;/span&gt;
&lt;span class="sr"&gt;/R2D2/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"R2D2"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="sr"&gt;/R2D2/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"r2d2"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; false (case sensitive)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Special Characters
&lt;/h4&gt;

&lt;p&gt;Now those could all have been &lt;code&gt;==&lt;/code&gt; compares instead, so let's look at a few more interesting characters:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;.&lt;/code&gt; - Matches any one character.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;*&lt;/code&gt; - Matches zero or more of whatever comes before it.&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;+&lt;/code&gt; - Matches one or more of whatever comes before it.&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Going back to examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The regular expression . will match any single-character&lt;/span&gt;
&lt;span class="c1"&gt;# string including r and % and ~.&lt;/span&gt;
&lt;span class="n"&gt;dot_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/./&lt;/span&gt;

&lt;span class="n"&gt;dot_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"r"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;dot_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"%"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;dot_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"~"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# In the same way, two periods ( .. ) will match any two characters,&lt;/span&gt;
&lt;span class="c1"&gt;# perhaps xx or 4F or even [!, but won’t match Q since it’s one,&lt;/span&gt;
&lt;span class="c1"&gt;# not two, characters long.&lt;/span&gt;
&lt;span class="n"&gt;double_dot_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/../&lt;/span&gt;

&lt;span class="n"&gt;double_dot_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"xx"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;double_dot_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"4F"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;double_dot_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"[!"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;double_dot_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"Q"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; false (one character)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Literal Characters
&lt;/h4&gt;

&lt;p&gt;There are some characters you want to match an actual dot, so how does one get Regex to do that? With a backslash:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# \. will match a literal dot.&lt;/span&gt;
&lt;span class="sr"&gt;/\./&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"."&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# 3\.14 will match the string version of PI to two decimal places,&lt;/span&gt;
&lt;span class="c1"&gt;# complete with the decimal point: 3.14&lt;/span&gt;
&lt;span class="sr"&gt;/3\.14/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"3.14"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Mr\. Olsen will match exactly one thing: Mr. Olsen&lt;/span&gt;
&lt;span class="sr"&gt;/Mr\. Olsen/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"Mr. Olsen"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Combining Effects
&lt;/h4&gt;

&lt;p&gt;The book then goes into a few combos, let's turn those into examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The regular expression A. will match any two-character string that&lt;/span&gt;
&lt;span class="c1"&gt;# starts with a capital A, including AM, An, At, and even A=.&lt;/span&gt;
&lt;span class="n"&gt;a_dot&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/A./&lt;/span&gt;

&lt;span class="n"&gt;a_dot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"AM"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;a_dot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"An"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;a_dot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"At"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;a_dot&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"A="&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Similarly, ...X will match any four-character string that ends&lt;/span&gt;
&lt;span class="c1"&gt;# with an X, including UVWX and XOOX.&lt;/span&gt;
&lt;span class="n"&gt;x_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/...X/&lt;/span&gt;

&lt;span class="n"&gt;x_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"UVWX"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;x_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"XOOX"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# The regular expression .r\. Smith will match both Dr. Smith as&lt;/span&gt;
&lt;span class="c1"&gt;# well as Mr. Smith but not Mrs. Smith.&lt;/span&gt;
&lt;span class="n"&gt;smith_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/.r\. Smith/&lt;/span&gt;

&lt;span class="n"&gt;smith_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"Dr. Smith"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;smith_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"Mr. Smith"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;smith_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt; &lt;span class="s2"&gt;"Mrs. Smith"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Sets, Ranges, and Alternatives
&lt;/h3&gt;

&lt;p&gt;Say you wanted a character out of a set of them, Regex enables this with &lt;code&gt;[]&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;vowel_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/[aeiou]/&lt;/span&gt;
&lt;span class="n"&gt;digit_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/[0123456789]/&lt;/span&gt;
&lt;span class="n"&gt;hex_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/[0123456789abdef]/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Think of them as inclusion in a set of characters. The book then goes on into a few more examples here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The regular expression [Rr]uss [Oo]lsen will match my name, with or without&lt;/span&gt;
&lt;span class="c1"&gt;# leading capitals.&lt;/span&gt;
&lt;span class="sr"&gt;/[Rr]uss [Oo]lsen/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Russ Olsen"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# More practically, you could use [0123456789abcdef][0123456789abcdef] to&lt;/span&gt;
&lt;span class="c1"&gt;# pick out a two-digit hexadecimal number like 3e or ff.&lt;/span&gt;
&lt;span class="n"&gt;two_digit_hex_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/[0123456789abcdef][0123456789abcdef]/&lt;/span&gt;
&lt;span class="n"&gt;two_digit_hex_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"3e"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;two_digit_hex_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ff"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# You can also use [aApP][mM] to match am or PM and anything in between,&lt;/span&gt;
&lt;span class="c1"&gt;# like aM or Pm.&lt;/span&gt;
&lt;span class="n"&gt;meridiem_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/[aApP][mM]/&lt;/span&gt;
&lt;span class="n"&gt;meridiem_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"am"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;meridiem_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"AM"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;meridiem_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"aM"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;meridiem_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"pm"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;meridiem_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"pM"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Ranges
&lt;/h4&gt;

&lt;p&gt;Now if that all seems a bit tedious there's the concept of a range in Regex:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="sr"&gt;/[a-z]/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"x"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="sr"&gt;/[0-9]/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"4"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Common Set Shortcuts
&lt;/h4&gt;

&lt;p&gt;...and the even more useful common set shortcuts:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Any number&lt;/span&gt;
&lt;span class="sr"&gt;/\d/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"0"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Any letter, number, or underscore&lt;/span&gt;
&lt;span class="sr"&gt;/\w/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"c"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Any whitespace like space, tab, and newline&lt;/span&gt;
&lt;span class="sr"&gt;/\s/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;" "&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h4&gt;
  
  
  Alternatives
&lt;/h4&gt;

&lt;p&gt;The last in this section is the alternative, which you can think more of as "OR":&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# A|B will match either A or B.&lt;/span&gt;
&lt;span class="sr"&gt;/A|B/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="sr"&gt;/A|B/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"B"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# AM|PM will match either AM or PM.&lt;/span&gt;
&lt;span class="sr"&gt;/AM|PM/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"AM"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="sr"&gt;/AM|PM/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"PM"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Batman|Spiderman will match the name of one of the two superheros.&lt;/span&gt;
&lt;span class="sr"&gt;/Batman|Spiderman/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Batman"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="sr"&gt;/Batman|Spiderman/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Spiderman"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book goes on to mention that you can use as many alternatives as you would like, but also sneaks in group captures (&lt;code&gt;()&lt;/code&gt;) here which I don't believe it gets into later, but trust me when I say that's one of the most useful parts of Regex.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Regular Expression Star
&lt;/h3&gt;

&lt;p&gt;Interestingly we mentioned this above in special characters, the star (&lt;code&gt;*&lt;/code&gt;) stands for zero or more of whatever is before it, and the plus (&lt;code&gt;+&lt;/code&gt;) stands for one or more. There's one more idea here with specifying count, but that's an item for later.&lt;/p&gt;

&lt;p&gt;The book mentions the following examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# AB* will match AB—that’s an A followed by one B.&lt;/span&gt;
&lt;span class="sr"&gt;/AB*/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"AB"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# AB* will also match ABB as well as ABBBBBBBB—remember, it’s an A followed&lt;/span&gt;
&lt;span class="c1"&gt;# by any number of B’s.&lt;/span&gt;
&lt;span class="sr"&gt;/AB*/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ABB"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="sr"&gt;/AB*/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ABBBBBBBB"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Don’t forget that AB* will also match plain old A—any number of B’s&lt;/span&gt;
&lt;span class="c1"&gt;# includes no B’s at all.&lt;/span&gt;
&lt;span class="sr"&gt;/AB*/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"A"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we were to switch to &lt;code&gt;+&lt;/code&gt; that last case wouldn't work. The book then goes on to mention that sets, ranges, and common sets work with &lt;code&gt;*&lt;/code&gt; as well. Really, anything does:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Zero or more vowels&lt;/span&gt;
&lt;span class="sr"&gt;/[aeiou]*/&lt;/span&gt;

&lt;span class="c1"&gt;# Zero or more numbers&lt;/span&gt;
&lt;span class="sr"&gt;/[0–9]*/&lt;/span&gt;
&lt;span class="sr"&gt;/\d*/&lt;/span&gt;

&lt;span class="c1"&gt;# Zero or more hex digits, lowercase&lt;/span&gt;
&lt;span class="sr"&gt;/[0-9a-f]*/&lt;/span&gt;

&lt;span class="c1"&gt;# Zero or more of any character&lt;/span&gt;
&lt;span class="sr"&gt;/.*/&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That last one the book mentions can be extremely useful, and is frequently used to make more flexible patterns:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="sr"&gt;/George.*/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"George Smith"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="sr"&gt;/.*George/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Sally George"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="sr"&gt;/.*George.*/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Jimmy George Joeseph"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Personally I would advocate for being more explicit about what you expect, lest you match more than you intended. Perhaps you do want to match a lot more, that's fine too, but make sure that's the case.&lt;/p&gt;

&lt;h4&gt;
  
  
  Regular Expression Counts
&lt;/h4&gt;

&lt;p&gt;The book does not mention this, but it's an important subject to bring up: counts. Star is used for zero or more, plus for one or more, question for optional, but what about if I wanted something like 4 to 5 instances?&lt;/p&gt;

&lt;p&gt;There are four count matches you'll want to be aware of:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Exactly 3 of a&lt;/span&gt;
&lt;span class="sr"&gt;/a{3}/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"aaa"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# 3 or more of a&lt;/span&gt;
&lt;span class="sr"&gt;/a{3,}/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"aaaa"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Between 3 and 6 of a&lt;/span&gt;
&lt;span class="sr"&gt;/a{3,6}/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"aaaaa"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Up to 6 of a&lt;/span&gt;
&lt;span class="sr"&gt;/a{,6}/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"aaaaa"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Do note though that unless used in conjunction with the section "Beginnings and Ends" coming up it won't work as intended, so be sure to give that a look and see if you can spot the flaws in the above matches.&lt;/p&gt;

&lt;h3&gt;
  
  
  Regular Expressions in Ruby
&lt;/h3&gt;

&lt;p&gt;Up to this point the book is just mentioning the Regex language without really getting into the Ruby implementation. For me and this article, however, I used Ruby implementations to show how it would work, so a lot of this will seem familiar.&lt;/p&gt;

&lt;p&gt;I'll give an overview instead of what it mentions.&lt;/p&gt;

&lt;h4&gt;
  
  
  Equal Squiggly (&lt;code&gt;=~&lt;/code&gt;)
&lt;/h4&gt;

&lt;p&gt;The equal squiggly sign is used for matching in Ruby, though it's not the clearest syntax:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="sr"&gt;/\d\d:\d\d (AM|PM)/&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="s1"&gt;'10:24 PM'&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; 0&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Why zero? That's the position in the string it found the match at. If there was nothing in there we'd get &lt;code&gt;nil&lt;/code&gt; back instead.&lt;/p&gt;

&lt;p&gt;Personally I prefer &lt;code&gt;match?&lt;/code&gt; as it returns back an explicit true or false, is faster, and very rarely do I need to know the direct index of something.&lt;/p&gt;

&lt;h4&gt;
  
  
  Regex Flags
&lt;/h4&gt;

&lt;p&gt;The book does sneak a fast one in here with Regex flags like &lt;code&gt;i&lt;/code&gt; which makes things case-insensitive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;merediem_match&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sr"&gt;/AM|PM/i&lt;/span&gt;

&lt;span class="n"&gt;merediem_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"am"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;span class="n"&gt;merediem_match&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"pm"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There are several more you can find at the bottom of rubular, but the common ones I use are &lt;code&gt;i&lt;/code&gt; for case-insensitive and &lt;code&gt;x&lt;/code&gt; for whitespace-insensitive.&lt;/p&gt;

&lt;h4&gt;
  
  
  Methods Taking Regex
&lt;/h4&gt;

&lt;p&gt;There are also methods like &lt;code&gt;sub&lt;/code&gt;, &lt;code&gt;gsub&lt;/code&gt;, &lt;code&gt;scan&lt;/code&gt;, and others which take in a Regex, like this example the book provides:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;
  &lt;span class="c1"&gt;# ...&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;obscure_times!&lt;/span&gt;
    &lt;span class="vi"&gt;@content&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\d\d:\d\d (AM|PM)/i&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"**:** **"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: I did add the &lt;code&gt;i&lt;/code&gt; there, where the book omits it. Case-insensitive would be more flexible here.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Beginnings and Ends
&lt;/h4&gt;

&lt;p&gt;The book then mentions that the Regex we've used so far are unbounded, meaning they match anywhere in a string. There are a few more special expressions that allow us to specify beginning and end of line, and beginning and end of strings:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Matches beginning of String&lt;/span&gt;
&lt;span class="sr"&gt;/\ASome text/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Some text starts this"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Matches end of String&lt;/span&gt;
&lt;span class="sr"&gt;/Some text\z/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ends with Some text"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Matches beginning of any line in a string&lt;/span&gt;
&lt;span class="sr"&gt;/^Some text/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Other text&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Some text"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;

&lt;span class="c1"&gt;# Matches end of any line in a String&lt;/span&gt;
&lt;span class="sr"&gt;/Some text$/&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;match?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"Some text&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;Other text"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; true&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Especially when dealing with user input you want to be exceptionally strict about this, and most Rails security tools are going to give you grief over omitting explicit beginning and ending of String signifiers in your Regex.&lt;/p&gt;

&lt;h3&gt;
  
  
  In the Wild
&lt;/h3&gt;

&lt;p&gt;The book mentions a real-world usecase as timezone offsets in &lt;code&gt;time.rb&lt;/code&gt;, notedly numeric ones like &lt;code&gt;-07:00&lt;/code&gt; or &lt;code&gt;+08:00&lt;/code&gt;, with this line:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="sr"&gt;/\A([+-])(\d\d):?(\d\d)\z/&lt;/span&gt; &lt;span class="o"&gt;=~&lt;/span&gt; &lt;span class="n"&gt;zone&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book mentions question mark (&lt;code&gt;?&lt;/code&gt;) as being an optional character, meaning there could be a colon there, or there could not be.&lt;/p&gt;

&lt;p&gt;Now the interesting part, and what the book wants to highlight, is that if the Regex isn't matched it's compared against a set of values like &lt;code&gt;UTC&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="no"&gt;ZoneOffset&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;zone&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which mixes the usefulness of Regex with the usefulness of set inclusion. That said, one could also do this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;zome_offset_matches&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;union&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="no"&gt;ZoneOffset&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which I've gotten a good deal of mileage out of in the past&lt;/p&gt;

&lt;h3&gt;
  
  
  Staying Out of Trouble
&lt;/h3&gt;

&lt;p&gt;The book mentions watching out for using &lt;code&gt;==&lt;/code&gt; accidentally in place of &lt;code&gt;=~&lt;/code&gt;, though to avoid that I would still actively recommend using &lt;code&gt;match?&lt;/code&gt; instead as clear naming means a lot when reading your code later.&lt;/p&gt;

&lt;p&gt;The second it mentions is &lt;code&gt;0&lt;/code&gt; being falsy in C-like languages, despite being truthy in Ruby and representing something was found at the 0th index of a String.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;There's a ton to cover any time Regex comes up, and the book gives a solid start, though I do really wish they had spent a bit of time on capture groups and counts.&lt;/p&gt;

&lt;p&gt;I may do a writeup or addendum to this chapter later on capture groups if there's interest, let me know!&lt;/p&gt;

&lt;p&gt;Next up we'll have Symbols, one of the more confusing aspects of Ruby.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>books</category>
    </item>
    <item>
      <title>Tales of the Autistic Developer - Loud Loud World</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Sun, 17 Oct 2021 06:14:37 +0000</pubDate>
      <link>https://dev.to/baweaver/tales-of-the-autistic-developer-loud-loud-world-122c</link>
      <guid>https://dev.to/baweaver/tales-of-the-autistic-developer-loud-loud-world-122c</guid>
      <description>&lt;p&gt;For those who don't know me, I'm autistic. I've been a developer for the better part of a decade.&lt;/p&gt;

&lt;p&gt;I didn't find out I was ASD until 19, and didn't reconcile with that until years later. These posts will be a combination of advice I've given to those who are like me, as well as a letter of sorts to my past self who could have used a lot of it.&lt;/p&gt;

&lt;p&gt;I write these posts in the hopes that someone like me will find value in knowing a very simple and very important truth about ASD:&lt;/p&gt;

&lt;p&gt;&lt;em&gt;You are not alone, and you are loved.&lt;/em&gt;&lt;/p&gt;

&lt;h2&gt;
  
  
  Loud Loud World
&lt;/h2&gt;

&lt;p&gt;For autistic people the world is so very loud, and I fear that this has led to a very common misunderstanding of our experience.&lt;/p&gt;

&lt;p&gt;It's not that we lack the capacity for things like listening, eating, empathy, or so many other skills as much as we're in a near-constant state of being overwhelmed by everything around us.&lt;/p&gt;

&lt;p&gt;This post is less about solutions, and more about my experience as a disability. So many would like to frame what I have as a "superpower" but deny the handicaps I face, so I'd like to take this time to write on the struggles I face on a daily basis.&lt;/p&gt;

&lt;h3&gt;
  
  
  I Can Hear Everything
&lt;/h3&gt;

&lt;p&gt;A common complaint of myself as a child is I was never paying attention, would frequently ask folks to repeat things, and in general just not "hear".&lt;/p&gt;

&lt;p&gt;Ironically I was also mocked for having near supernatural hearing abilities. If my name was mentioned or any other trigger word for a hobby I would hear it, even clear across a room.&lt;/p&gt;

&lt;p&gt;The misconceptions of the first section are a direct result of the second. It's not that I couldn't hear, but that I heard too much.&lt;/p&gt;

&lt;p&gt;My brain is constantly on, and I experience everything at once. I can't turn it off, I don't know how and there aren't any great solutions I've found beyond noise cancelling headphones and moving out of noisy environments.&lt;/p&gt;

&lt;p&gt;Heck, I can hear electricity in the walls. Did you know it makes noise, because I certainly do. A short in an electronic device will scream at me, and with it my focus goes right out a window.&lt;/p&gt;

&lt;p&gt;I'm most certainly not ignoring you when you're talking, in fact I'm reminding myself to pay attention in my head on repeat, but if a loud noise or something troubling happens my attention is gone. You could talk about my favorite hobbies and I'd still twitch at anything around me happening, try as I might to stop it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Smell Everything
&lt;/h3&gt;

&lt;p&gt;In elementary school I was quite viciously mocked for smelling things, including by a teacher who egged it on. A lot of trauma in me realizing who I was could be traced to teachers like this, but back to the point I could smell anything around.&lt;/p&gt;

&lt;p&gt;If lunch was being prepared I could tell you exactly what it was (if I'd experienced it before), what burned, what flavor the gum under the table probably was, and whether or not my classmates had just been to gym class.&lt;/p&gt;

&lt;p&gt;Just in the past year I'd smelled rain and heard a dropping that led me to find a small leak in one of the doors of my home.&lt;/p&gt;

&lt;p&gt;It wasn't unusual for this to make me slightly sick, as scent is very closely tied to taste.&lt;/p&gt;

&lt;p&gt;Any more I've taken to a habit of wearing a certain amount of cologne as a centering scent to try and distract me from doing this. Most of my coping follows a similar strategy of dulling my senses.&lt;/p&gt;

&lt;h3&gt;
  
  
  Taste Overload
&lt;/h3&gt;

&lt;p&gt;Some would call me a picky eater, they're probably right. If something is unfamiliar to me it's overwhelming, and certain textures and combinations for some reason will make me physically sick.&lt;/p&gt;

&lt;p&gt;The annoying part is that I don't always know what those textures or combinations might be.&lt;/p&gt;

&lt;p&gt;It's been a perpetual fear of mine that I might offend someone by not being able to eat their cooking, so many times I'll try anyways and end up making myself sick for a few days afterwards.&lt;/p&gt;

&lt;p&gt;Back in college there was an eating competition where they gave us tacos with lettuce. Those who know me would know that  that's one thing which will absolutely make me visibly sick within seconds, so I had to drop out.&lt;/p&gt;

&lt;p&gt;This certainly does not make it easy to find a balanced diet, and trust me I do try. It's also why I order the exact same thing every time I go to the same restaurant. I know it's safe, and safe matters a lot to me, which is how I cope.&lt;/p&gt;

&lt;h3&gt;
  
  
  Visual Stimulus
&lt;/h3&gt;

&lt;p&gt;Now I'm not at the point of epilepsy, but flashing gifs and reactions will wreck my concentration. I'm very happy that Slack added an option to turn them off or I'd never get anything done.&lt;/p&gt;

&lt;p&gt;My vision isn't perfect, I wear glasses, but any visual stimulus around me sends my head into full alert mode. It's also why you'll catch me closing one eye outside, or closing both if I'm thinking.&lt;/p&gt;

&lt;h3&gt;
  
  
  Touch and Feel
&lt;/h3&gt;

&lt;p&gt;There are even fabrics and various textures that if I touch or have to keep on I get very uncomfortable with. Fabric tags, wools (especially socks), seams, and other things some folks can ignore will drive me up a wall.&lt;/p&gt;

&lt;p&gt;If there's so much as a small pebble that gets into my shoe it's going to annoy me the entire day until I get it out, including ones embedded in the bottom of my sole.&lt;/p&gt;

&lt;h3&gt;
  
  
  Emotional Overload
&lt;/h3&gt;

&lt;p&gt;People have called me a robot for years, slightly monotone voice, and a seeming absence of cognizance of emotions. Sure, there's some truth to that, I don't social well all the time and I had to learn those rules the hard way.&lt;/p&gt;

&lt;p&gt;What isn't true, however, is that I don't feel. Quite the contrary.&lt;/p&gt;

&lt;p&gt;I have to turn off news, social media, and stop talking to people because once I hear problems I become deeply invested in fixing them. My mind is hard-wired like that, I want to help, and I'm far too easy to bait into things.&lt;/p&gt;

&lt;p&gt;As a result I've had to become exceptionally cautious in how much I talk to others outside of close groups. The real annoyance is I can feel their pain, but I have no idea how to respond appropriately, so rather than try I frequently have to wait and internalize that pain which is not healthy.&lt;/p&gt;

&lt;p&gt;I hate that I cannot fix everything, so instead I try and focus on what I know I can have an impact on and direct my attentions there. Doesn't help that sick feeling though knowing how much more pain there is in the world.&lt;/p&gt;

&lt;h3&gt;
  
  
  Temporal Hijinks
&lt;/h3&gt;

&lt;p&gt;I have no concept of time. People at work would disagree with me on that and comment that I show up early to things, know exactly when things are happening, and am generally on top of it.&lt;/p&gt;

&lt;p&gt;That's only because I have alarms for everything, calendar reminders, sticky notes, and entire systems meant to keep me on track. I adhere to strict schedules, and should I break those schedules I'll burn out hard and lose my sense of self for at least a few weeks while I recover and recalibrate.&lt;/p&gt;

&lt;p&gt;It's a similar reason to why I despise phone calls and synchronous events which require presence, as they'll ruin the entire rest of my day for getting anything done.&lt;/p&gt;

&lt;p&gt;The irony, as it tends to be, is that all of these systems got me promoted into roles where it's my job to be on top of such things.&lt;/p&gt;

&lt;h3&gt;
  
  
  The Migraines
&lt;/h3&gt;

&lt;p&gt;When the world is too much, when anxiety gets to me, and when I just can't turn it off my body will eventually take drastic measures and start me into a series of migraines that will have me laid up in bed for at least a full day, often times two to three days.&lt;/p&gt;

&lt;p&gt;As I get close to that point I will be very short tempered and intentional with my time, trying to jettison anything and everything that's not completely relevant to tasks at hand that are required to get done. I start going into lockdown mode to protect myself, and if I miss I'm going to be out of it for potentially multiple days.&lt;/p&gt;

&lt;p&gt;If I keep ignoring it? Burnout is a very real threat for me, and one that I have to be exceptionally cautious of. Some would say enjoying what you do is a cure, but if anything that's the curse which has me constantly flirting with the line where I'm not coming back for a good couple of months beyond rote and repetition.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrapping Up
&lt;/h2&gt;

&lt;p&gt;If there's one thing I want people to get out of this, it's that I'm a whole human. You don't get all the benefits of autism without the drawbacks, and the drawbacks make you no less valid of love and acceptance.&lt;/p&gt;

&lt;p&gt;Over the years I've had great success in the industry, but many would erase my disability, and in doing such they would discriminate against those with similar issues. To only write of the good, and never the bad, would be dishonest.&lt;/p&gt;

&lt;p&gt;So I wrap up today by saying that I'm me, flaws and all. It's a loud loud world out there, and we do our best to participate in it.&lt;/p&gt;

</description>
      <category>autism</category>
      <category>mentalhealth</category>
    </item>
    <item>
      <title>Let's Read – Polished Ruby Programming – Ch 3.2 Instance Variables</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Tue, 28 Sep 2021 05:57:22 +0000</pubDate>
      <link>https://dev.to/baweaver/let-s-read-polished-ruby-programming-ch-3-2-instance-variables-4jl4</link>
      <guid>https://dev.to/baweaver/let-s-read-polished-ruby-programming-ch-3-2-instance-variables-4jl4</guid>
      <description>&lt;p&gt;&lt;a href="https://www.packtpub.com/product/polished-ruby-programming/9781801072724"&gt;Polished Ruby Programming&lt;/a&gt; is a recent release by &lt;a href="https://twitter.com/jeremyevans0"&gt;Jeremy Evans&lt;/a&gt;, a well known Rubyist working on the Ruby core team, Roda, Sequel, and several other projects. Knowing Jeremy and his experience this was an instant buy for me, and I look forward to what we learn in this book.&lt;/p&gt;

&lt;p&gt;You can find the book here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.packtpub.com/product/polished-ruby-programming/9781801072724"&gt;https://www.packtpub.com/product/polished-ruby-programming/9781801072724&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This review, like other "Let's Read" series in the past, will go through each of the chapters individually and will add commentary, additional notes, and general thoughts on the content. Do remember books are limited in how much information they can cram on a page, and they can't cover everything.&lt;/p&gt;

&lt;p&gt;With that said let's go ahead and get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 3 – Proper Variable Usage – Instance Variables
&lt;/h2&gt;

&lt;p&gt;The third chapter covers the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using Ruby's favorite variable type – the local variable

&lt;ul&gt;
&lt;li&gt;Increasing performance by adding local variables&lt;/li&gt;
&lt;li&gt;Avoiding unsafe optimizations&lt;/li&gt;
&lt;li&gt;Handling scope gate issues&lt;/li&gt;
&lt;li&gt;Naming considerations with local variables&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Learning how best to use instance variables

&lt;ul&gt;
&lt;li&gt;Increasing performance with instance variables&lt;/li&gt;
&lt;li&gt;Handling scope issues with instance variables&lt;/li&gt;
&lt;li&gt;Naming considerations for instance variables&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Understanding how constants are just a type of variable

&lt;ul&gt;
&lt;li&gt;Handling scope issues with constants&lt;/li&gt;
&lt;li&gt;Visibility differences between constants and class instance variables&lt;/li&gt;
&lt;li&gt;Naming considerations with constants&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Replacing class variables

&lt;ul&gt;
&lt;li&gt;Replacing class variables with constants&lt;/li&gt;
&lt;li&gt;Replacing class variables with class instance variables using the superclass lookup approach&lt;/li&gt;
&lt;li&gt;Replacing class variables with class instance variables using the copy to subclass approach&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Avoiding global variables, most of the time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll be covering instance variables in this section.&lt;/p&gt;

&lt;h4&gt;
  
  
  Increasing performance with instance variables
&lt;/h4&gt;

&lt;p&gt;As with the section on local variables you can also increase performance using instance variables, but primarily through caching techniques. The book mentions this in terms of idempotency and storing the results of calculations, but personally I prefer cache as a more approachable term.&lt;/p&gt;

&lt;p&gt;It then goes to this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;LineItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line_items&lt;/span&gt;
    &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total_tax&lt;/span&gt;
    &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It mentions that if &lt;code&gt;total_tax&lt;/code&gt; is only called once then there's not much value in caching, but if it gets called multiple times it could be worthwhile as the next example shows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total_tax&lt;/span&gt;
  &lt;span class="vi"&gt;@total_tax&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Before we continue with the book you'll notice common convention here is to use the name of the method as the name of the instance variable. I've also seen &lt;code&gt;@_total_tax&lt;/code&gt; as an indication that it's a "private" instance variable rather than one that should be freely accessed, but that comes down to preference.&lt;/p&gt;

&lt;p&gt;The book goes on to mention cases where &lt;code&gt;||=&lt;/code&gt; won't work, which is a very useful topic as I've seen that trip people a lot in production code. Those cases are around &lt;code&gt;false&lt;/code&gt; and &lt;code&gt;nil&lt;/code&gt;, and cases where those are legitimate return values you want to remember versus ones you want to override. The book mentions &lt;code&gt;defined?&lt;/code&gt; as a way around this with a guard statement:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total_tax&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@total_tax&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="vi"&gt;@total_tax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="vi"&gt;@total_tax&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now for that particular case it won't make sense for that above concern, but it does prevent that &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt; issue when it comes up for other caching concerns.&lt;/p&gt;

&lt;p&gt;The book also mentions here that &lt;code&gt;defined?&lt;/code&gt; is more easily optimized by Ruby over &lt;code&gt;instance_variable_defined?&lt;/code&gt;, as the former is a keyword rather than a Ruby method.&lt;/p&gt;

&lt;p&gt;The other case where that caching technique will break is around frozen classes, which may be rarer. The books solution is as follows:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;LineItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line_items&lt;/span&gt;
    &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;
    &lt;span class="vi"&gt;@cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

    &lt;span class="nb"&gt;freeze&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total_tax&lt;/span&gt;
    &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:total_tax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;||=&lt;/span&gt; &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Personally I find this against the spirit of freezing as you're modifying the internal &lt;code&gt;Hash&lt;/code&gt;. If someone was going for purity here they'd likely return a new frozen instance with that variable pre-populated.&lt;/p&gt;

&lt;p&gt;As with the previous example set this one is also weak to &lt;code&gt;false&lt;/code&gt; or &lt;code&gt;nil&lt;/code&gt; values which can be combated as such with &lt;code&gt;key?&lt;/code&gt; in the place of &lt;code&gt;defined?&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;total_tax&lt;/span&gt;
  &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:total_tax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;key?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:total_tax&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

  &lt;span class="vi"&gt;@cache&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:total_tax&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book goes on to mention that when dealing with instance variables you do not have control over them as completely as you might with a local. What's to stop someone from modifying &lt;code&gt;@tax_rate&lt;/code&gt; somewhere else? Not much in Ruby.&lt;/p&gt;

&lt;p&gt;It also mentions that data being passed in could also be changed which can cause issues with caching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Foo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;

&lt;span class="n"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.095&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tax_was&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total_tax&lt;/span&gt;

&lt;span class="n"&gt;line_items&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Bar'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;4.2&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;tax_is&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total_tax&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which is a great point to make, as some get too eager in caching and don't consider potential legitimate cases where values can change. In this particular one it's not the intent of the program, so it's more a negative thing.&lt;/p&gt;

&lt;p&gt;The book mentions getting around this by getting a cleanly duplicated copy of the line items:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;
  &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;
  &lt;span class="vi"&gt;@cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nb"&gt;freeze&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...or using &lt;code&gt;line_items.freeze&lt;/code&gt; instead. Or even just using the best of both by using &lt;code&gt;line_items.dup.freeze&lt;/code&gt; to more completely guard against shenanigans.&lt;/p&gt;

&lt;p&gt;Ah, speaking of shenanigans, someone could modify the line items themselves as the book mentions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Foo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;span class="n"&gt;invoice&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;0.095&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;tax_was&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total_tax&lt;/span&gt;

&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;100&lt;/span&gt;

&lt;span class="n"&gt;tax_is&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;total_tax&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...in which the solution is to make sure line items are also frozen:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;LineItem&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Struct&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;

    &lt;span class="nb"&gt;freeze&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...or to freeze them in the &lt;code&gt;Invoice#initialize&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="vi"&gt;@line_items&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;dup&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;

  &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;tax_rate&lt;/span&gt;
  &lt;span class="vi"&gt;@cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;

  &lt;span class="nb"&gt;freeze&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Turns out caching is hard, frozen objects can make it somewhat easier, but a particularly determined person can find a way either explicitly or inadvertently. It's definitely good to cover the myriad of concerns that can go wrong in terms of caching, as it's a very hard problem in all of programming in general.&lt;/p&gt;

&lt;h4&gt;
  
  
  Handling scope issues with instance variables
&lt;/h4&gt;

&lt;p&gt;Unlike local variables instance variables are scoped to the receiver, or self, as the book mentions. For me that's always meant that an instance variable is fetched from the context it's evaluated in, but for most folks the concern stops that it's seen in the scope of the current instance of a class they're working with.&lt;/p&gt;

&lt;p&gt;Why the extra complexity there? Well there are some parts of Ruby that can change the context being evaluated like &lt;code&gt;define_method&lt;/code&gt;, &lt;code&gt;Class.new&lt;/code&gt;, &lt;code&gt;Module.new&lt;/code&gt;, and a few others the book doesn't get into like &lt;code&gt;instance_eval&lt;/code&gt; and friends where you can play with the &lt;code&gt;binding&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The book mentions that instance variables can be in a different context, and the example it gives is a block passed to something you don't own:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;line_item_taxes&lt;/span&gt;
    &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now for this one &lt;code&gt;map&lt;/code&gt; isn't doing anything particularly odd, but that's assuming as the book says that &lt;code&gt;@line_items&lt;/code&gt; is an &lt;code&gt;Array&lt;/code&gt; containing &lt;code&gt;LineItem&lt;/code&gt; objects which happen to respond to certain methods. Usually, a fairly safe assumption, but the book goes into when it might not be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;LineItemList&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;Invoice&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;LineItemList&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;([&lt;/span&gt;&lt;span class="s1"&gt;'Foo'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mf"&gt;3.5&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;]),&lt;/span&gt; &lt;span class="mf"&gt;0.095&lt;/span&gt;&lt;span class="n"&gt;r&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book goes into the reasoning you might want to do this, but breaking down the code for a moment first:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;super&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;price&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Potential variations:&lt;/span&gt;
&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="no"&gt;LineItem&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;:new&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This will convert any item passed in into a &lt;code&gt;LineItem&lt;/code&gt; and forward it on to the &lt;code&gt;Array&lt;/code&gt; constructor.&lt;/p&gt;

&lt;p&gt;The next part on &lt;code&gt;map&lt;/code&gt; is a bit more interesting:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;map&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;super&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;instance_eval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;block&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It'll forward to the underlying &lt;code&gt;map&lt;/code&gt;, but evaluates the block not in the context of the class, but in the context of the item itself. Why? Well the book gets into that.&lt;/p&gt;

&lt;p&gt;The reasons provided are:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Initialization&lt;/strong&gt; - Faster to create items via &lt;code&gt;Array&lt;/code&gt; than manually constructing each one.&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Ease of Access&lt;/strong&gt; - Provides direct access to methods in the instance&lt;/li&gt;
&lt;li&gt;
&lt;strong&gt;Less Verbosity&lt;/strong&gt; - Allows omission of &lt;code&gt;item&lt;/code&gt;
&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;For point 3 the following code is provided:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;line_item_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="n"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;quantity&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Versus the more verbose:&lt;/span&gt;
&lt;span class="n"&gt;line_item_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book goes on to mention that this breaks the above example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;line_item_taxes&lt;/span&gt;
    &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="vi"&gt;@tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;@tax_rate&lt;/code&gt; is no longer visible. There are workarounds with local variables like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Invoice&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;line_item_taxes&lt;/span&gt;
    &lt;span class="n"&gt;tax_rate&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="vi"&gt;@tax_rate&lt;/span&gt;
    &lt;span class="vi"&gt;@line_items&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="n"&gt;tax_rate&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;price&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="n"&gt;item&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;quantity&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;But as the book mentions, and I would agree, you're deviating far enough from common-use Ruby to be obtuse. The brevity you gain comes at the loss of intuitive clarity in your code, and should give a developer pause before trying such solutions.&lt;/p&gt;

&lt;p&gt;A small amount of verbosity is a very fair trade for making code easier to understand, work with, and intuitively grasp its underlying structures. A good rule to keep in mind is to do the least surprising thing possible, because one day you may very well be the one surprised by your own code.&lt;/p&gt;

&lt;h4&gt;
  
  
  Naming considerations for instance variables
&lt;/h4&gt;

&lt;p&gt;As with the previous section there really aren't too many differences in naming conventions between instance and local variables. They should be &lt;code&gt;@snake_cased&lt;/code&gt;, and prefer ASCII characters. The book mentions some potential exceptions around mirroring &lt;code&gt;@ClassNames&lt;/code&gt; and &lt;code&gt;@ModuleNames&lt;/code&gt;, but I would almost discourage that myself in favor of remaining consistent with &lt;code&gt;@snake_case&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;The benefit of instance variables, as mentioned, is that they come with inherent context. That means you can name them a bit more loosely than you might a local variable. A few examples are provided:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Too long&lt;/span&gt;
&lt;span class="vi"&gt;@transaction_processing_system_report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TransactionProcessingSystemReport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

&lt;span class="c1"&gt;# Better&lt;/span&gt;
&lt;span class="vi"&gt;@tps_report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TransactionProcessingSystemReport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;

&lt;span class="c1"&gt;# Best, if only one report is present&lt;/span&gt;
&lt;span class="vi"&gt;@report&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TransactionProcessingSystemReport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  Wrap Up
&lt;/h3&gt;

&lt;p&gt;With that we're finished up the section on instance variables.&lt;/p&gt;

&lt;p&gt;The next section will cover constants.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>books</category>
    </item>
    <item>
      <title>Let's Read – Eloquent Ruby – Ch 4</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Tue, 21 Sep 2021 06:55:44 +0000</pubDate>
      <link>https://dev.to/baweaver/let-s-read-eloquent-ruby-ch-4-c0m</link>
      <guid>https://dev.to/baweaver/let-s-read-eloquent-ruby-ch-4-c0m</guid>
      <description>&lt;p&gt;Perhaps my personal favorite recommendation for learning to program Ruby like a Rubyist, &lt;a href="http://eloquentruby.com/"&gt;Eloquent Ruby&lt;/a&gt; is a book I recommend frequently to this day. That said, it was released in 2011 and things have changed a bit since then.&lt;/p&gt;

&lt;p&gt;This series will focus on reading over Eloquent Ruby, noting things that may have changed or been updated since 2011 (around Ruby 1.9.2) to today (2021 — Ruby 3.0.x).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is an updated version of a previous unfinished Medium series of mine you can &lt;a href="https://medium.com/@baweaver/lets-read-eloquent-ruby-ch-1-b2115d1416a6"&gt;find here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Chapter 4. Take Advantage of Ruby’s Smart Strings
&lt;/h2&gt;

&lt;p&gt;This chapter starts into &lt;code&gt;String&lt;/code&gt;s, and the intro mentions something that I've found to be very true. Most folks would assume that programmers deal primarily in numbers, which sure we do, but far more often we're doing some form of text manipulation.&lt;/p&gt;

&lt;p&gt;Parsing data, serializing it back, user input, really so much of programming centers around text and &lt;code&gt;String&lt;/code&gt;s, where a lot of the rest of it ends up around collections. For me numbers are almost a distant third to those two, but that's a personal opinion.&lt;/p&gt;

&lt;h3&gt;
  
  
  Coming Up with a String
&lt;/h3&gt;

&lt;p&gt;So Ruby is Ruby, and the book mentions that there are several ways to make a &lt;code&gt;String&lt;/code&gt;, much like so many other things in Ruby. Generally the easy rule to follow for me has been to use double-quotes for everything, despite the (completely insignificant) performance difference with single quotes.&lt;/p&gt;

&lt;p&gt;Anyways, the book mentions a few examples of backslashes with single quotes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Escaping a single quote mark&lt;/span&gt;
&lt;span class="n"&gt;a_string_with_a_quote&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'Say it ain\'t so!'&lt;/span&gt;

&lt;span class="c1"&gt;# Escaping a backslash&lt;/span&gt;
&lt;span class="n"&gt;a_string_with_a_backslash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'This is a backslash: \\'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now the reason I say double quotes are going to be easier in general is that single quoted strings also treat things literally rather than evaluate special syntaxes:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;single_quoted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'I have a tab: \t and a newline: \n'&lt;/span&gt;
&lt;span class="n"&gt;double_quoted&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"I have a tab: &lt;/span&gt;&lt;span class="se"&gt;\t&lt;/span&gt;&lt;span class="s2"&gt; and a newline: &lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Same applies to interpolation, as the book mentions:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;author&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Ben Bova"&lt;/span&gt;
&lt;span class="n"&gt;title&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Mars"&lt;/span&gt;

&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;title&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; is written by &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;author&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="c1"&gt;# Mars is written by Ben Bova&lt;/span&gt;
&lt;span class="c1"&gt;#&lt;/span&gt;
&lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s1"&gt;'#{title} is written by #{author}'&lt;/span&gt;
&lt;span class="c1"&gt;# #{title} is written by #{author}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;One weakness of quotes in general is when you get them mixed in each other, as the books next few examples mentioned:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;Stop&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;, she said, &lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;I cannot deal with the backslashes.&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;

&lt;span class="c1"&gt;# versus using single quotes to wrap&lt;/span&gt;
&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'"Stop", she said, "I cannot deal with the backslashes."'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but as with the book, I also agree that this is where the &lt;code&gt;%q&lt;/code&gt; syntax is more useful:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;str&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%q("Stop", she said, "I can't live without 's and "s.")&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It also gets into the fact you could have used &lt;code&gt;%q[]&lt;/code&gt; or &lt;code&gt;%q$$&lt;/code&gt; or... anyways, probably best to prefer &lt;code&gt;%q()&lt;/code&gt; in general as it's easier to deal with.&lt;/p&gt;

&lt;p&gt;Now the next one to remember with &lt;code&gt;%q&lt;/code&gt; is it's the same as single quotes, where &lt;code&gt;%Q&lt;/code&gt; is double. As with my previous mention I would in general prefer double quotes unless you have a specific reason not to, or &lt;code&gt;%Q&lt;/code&gt; in these cases.&lt;/p&gt;

&lt;p&gt;The book then goes into Heredocs:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;multi_line&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
Here's a lot of text. Some
of it goes on multiple lines!
&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The weakness here the book does not mention is that &lt;code&gt;&amp;lt;&amp;lt;TAG&lt;/code&gt; syntax is space-sensitive:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;m1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
Here's a lot of text. Some
of it goes on multiple lines!
&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;

&lt;span class="n"&gt;m2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
    Here's a lot of text. Some
    of it goes on multiple lines!
&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So if you had some code like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Container&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Something&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a_method&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
        Text here that is slightly long
        because why not?
      EOF
    end
  end
end
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...all that indent to the left? That's now in the &lt;code&gt;String&lt;/code&gt;. You probably want the more recent "squiggly" heredoc syntax instead in general:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;Container&lt;/span&gt;
  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Something&lt;/span&gt;
    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a_method&lt;/span&gt;
      &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;~&lt;/span&gt;&lt;span class="no"&gt;EOF&lt;/span&gt;&lt;span class="sh"&gt;
        Text here that is slightly long
        because why not?
&lt;/span&gt;&lt;span class="no"&gt;      EOF&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;There aren't very many good reasons to use &lt;code&gt;&amp;lt;&amp;lt;&lt;/code&gt; versus &lt;code&gt;&amp;lt;&amp;lt;~&lt;/code&gt;, as the squiggly syntax auto-trims to the least indented line on the left, which is very very useful for long text.&lt;/p&gt;

&lt;h3&gt;
  
  
  Another API to Master
&lt;/h3&gt;

&lt;h4&gt;
  
  
  Stripping and Chomping
&lt;/h4&gt;

&lt;p&gt;As with &lt;code&gt;Array&lt;/code&gt; and so many other of Ruby's classes the real fun starts when you get into the methods they come with, and Ruby's &lt;code&gt;String&lt;/code&gt; class has several. The book starts off with &lt;code&gt;lstrip&lt;/code&gt; for one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s1"&gt;' hello'&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lstrip&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; 'hello'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and as intuition might serve, there's also an &lt;code&gt;rstrip&lt;/code&gt;, and a &lt;code&gt;strip&lt;/code&gt; which will take off of both ends. The more common one I use, and the book mentions, is &lt;code&gt;chomp&lt;/code&gt; which gets rid of newline and carriage return characters at the end of a &lt;code&gt;String&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"It was a dark and stormy night&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chomp&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "It was a dark and stormy night"&lt;/span&gt;

&lt;span class="c1"&gt;# ...but only one newline&lt;/span&gt;
&lt;span class="s2"&gt;"hello&lt;/span&gt;&lt;span class="se"&gt;\n\n\n&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chomp&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "hello\n\n"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now a method I always forget about, and haven't found much of a use for, &lt;code&gt;chop&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chop&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "hell"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...will knock off the last character no matter what it is. Personally I really haven't seen much of a use for this one, but that's me.&lt;/p&gt;

&lt;h4&gt;
  
  
  Case Manipulation
&lt;/h4&gt;

&lt;p&gt;Next the book gets into working with string cases:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;upcase&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "HELLO"&lt;/span&gt;

&lt;span class="s2"&gt;"HELLO"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "hello"&lt;/span&gt;

&lt;span class="s2"&gt;"Hello"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "hELLO"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;More recent versions have also added &lt;code&gt;capitalize&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"hello"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;capitalize&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "Hello"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which was formerly a Rails exclusive, but in common enough usage it makes sense.&lt;/p&gt;

&lt;h4&gt;
  
  
  Substitution
&lt;/h4&gt;

&lt;p&gt;Next up is substitution, allowing you to replace part of a string with another:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"It is warm outside"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"warm"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"cold"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "It is cold outside"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but that only works with one substitution. You'd want &lt;code&gt;gsub&lt;/code&gt; for multiple:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"yes yes"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"yes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"no"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "no yes"&lt;/span&gt;

&lt;span class="s2"&gt;"yes yes"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"yes"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"no"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "no no"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now be aware, the book doesn't mention this and leaves the bang (&lt;code&gt;sub!&lt;/code&gt;, &lt;code&gt;gsub!&lt;/code&gt;) variants of these methods to a bit later, but they have a dangerous difference.&lt;/p&gt;

&lt;p&gt;So as a reminder bang methods do something worthy of caution, typically mutating the underlying object. In many cases they'll return &lt;code&gt;nil&lt;/code&gt; if they make no modifications for optimization reasons, and the object if it does. That means chaining will throw you for a loop:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"abcd"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ab"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ba"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "badc"&lt;/span&gt;

&lt;span class="s2"&gt;"abcd"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"ac"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"ba"&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;sub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"cd"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"dc"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# NoMethodError (undefined method `sub!' for nil:NilClass)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Catch that? Most won't while coding with these methods, and it can be a real pesky source of bugs. In general avoid bang methods unless you really need the performance increase. Most of the time you won't.&lt;/p&gt;

&lt;h4&gt;
  
  
  Splitting
&lt;/h4&gt;

&lt;p&gt;Next up we have &lt;code&gt;split&lt;/code&gt;, which allows us to split &lt;code&gt;String&lt;/code&gt;s on a character, or whitespace if unspecified:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"It was a dark and stormy night"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["It", "was", "a", "dark", "and", "stormy", "night"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book then gives an example of a character-based split:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"Bill:Shakespeare:Playwright:Globe"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;":"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["Bill", "Shakespeare", "Playwright", "Globe"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but one thing is &lt;code&gt;split&lt;/code&gt; actually takes &lt;em&gt;two&lt;/em&gt; arguments, the delimiter (what separates items) and a count of how many items to max out on:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="sx"&gt;%Q(data: { "a": 1, "b": 2 })&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;":"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["data", " { \"a\"", " 1, \"b\"", " 2 }"]&lt;/span&gt;

&lt;span class="sx"&gt;%Q(data: { "a": 1, "b": 2 })&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;split&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;":"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["data", " { \"a\": 1, \"b\": 2 }"]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Notice it? It's subtle, but because the &lt;code&gt;String&lt;/code&gt; here is more of a key-value with the value being a JSON-like format it's not a good idea to split on &lt;code&gt;:&lt;/code&gt; globally, but once, where the key and value are separated. Granted you should probably also do &lt;code&gt;split(/: */, 2)&lt;/code&gt; to account for spaces between the two as well.&lt;/p&gt;

&lt;h4&gt;
  
  
  Lines, Characters, and Bytes
&lt;/h4&gt;

&lt;p&gt;One topic that's come up a few times is why a &lt;code&gt;String&lt;/code&gt; doesn't have an &lt;code&gt;each&lt;/code&gt; method. Well, it does and it doesn't. What'd be the iterated item? &lt;code&gt;String&lt;/code&gt;s are a collection of a lot of different concepts. Bytes, characters, codepoints, lines, and probably a lot more I'm forgetting. Point being there's not one clear iterable here.&lt;/p&gt;

&lt;p&gt;That's why Ruby lets you decide for yourself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"some&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;lines&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;of&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;text"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;lines&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["some\n", "lines\n", "of\n", "text"]&lt;/span&gt;

&lt;span class="s2"&gt;"some&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;lines&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;of&lt;/span&gt;&lt;span class="se"&gt;\n&lt;/span&gt;&lt;span class="s2"&gt;text"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_line&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;line&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;line&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# some&lt;/span&gt;
&lt;span class="c1"&gt;# lines&lt;/span&gt;
&lt;span class="c1"&gt;# of&lt;/span&gt;
&lt;span class="c1"&gt;# text&lt;/span&gt;
&lt;span class="c1"&gt;#  =&amp;gt; "some\nlines\nof\ntext"&lt;/span&gt;

&lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;chars&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; ["a", "b", "c"]&lt;/span&gt;

&lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_char&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# a&lt;/span&gt;
&lt;span class="c1"&gt;# b&lt;/span&gt;
&lt;span class="c1"&gt;# c&lt;/span&gt;
&lt;span class="c1"&gt;#  =&amp;gt; "abc"&lt;/span&gt;

&lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;bytes&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [97, 98, 99]&lt;/span&gt;

&lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_byte&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# 97&lt;/span&gt;
&lt;span class="c1"&gt;# 98&lt;/span&gt;
&lt;span class="c1"&gt;# 99&lt;/span&gt;
&lt;span class="c1"&gt;#  =&amp;gt; "abc"&lt;/span&gt;

&lt;span class="s2"&gt;"😅🎉✨"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;codepoints&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [128517, 127881, 10024]&lt;/span&gt;

&lt;span class="s2"&gt;"😅🎉✨"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_codepoint&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# 128517&lt;/span&gt;
&lt;span class="c1"&gt;# 127881&lt;/span&gt;
&lt;span class="c1"&gt;# 10024&lt;/span&gt;
&lt;span class="c1"&gt;#  =&amp;gt; "😅🎉✨"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book does mention that Ruby does allow &lt;code&gt;String&lt;/code&gt;s to be indexed against with &lt;code&gt;[]&lt;/code&gt; like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"abc"&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "a"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which implies it iterates on characters, but once you get into emoji and unicode and all the fun magics of non-ASCII &lt;code&gt;String&lt;/code&gt;s it starts getting a bit harder to work with.&lt;/p&gt;

&lt;p&gt;Do also remember, as the book puts at the end of the chapter, that &lt;code&gt;[-1]&lt;/code&gt; will get the last character and ranges are valid (&lt;code&gt;[3..5]&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="s2"&gt;"some text"&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "t"&lt;/span&gt;

&lt;span class="s2"&gt;"some text"&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "e t"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;h3&gt;
  
  
  In the Wild
&lt;/h3&gt;

&lt;p&gt;The book then goes into a few real-world examples of &lt;code&gt;String&lt;/code&gt; manipulation, starting with &lt;code&gt;html_escape&lt;/code&gt; from the standard library in the RSS library:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;html_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;amp;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;amp;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/\"/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;quot;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;gt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/&amp;lt;/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;lt;"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...though the &lt;code&gt;Hash&lt;/code&gt; form may be a bit easier to work with later:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;ESCAPED_ENTITIES_MAP&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"&amp;amp;"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;amp;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="se"&gt;\"&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;quot;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"&amp;gt;"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;gt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="s2"&gt;"&amp;lt;"&lt;/span&gt;  &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s2"&gt;"&amp;amp;lt;"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="no"&gt;ESCAPED_ENTITIES&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Regexp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;union&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ESCAPED_ENTITIES_MAP&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;keys&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;html_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;ESCAPED_ENTITIES&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="no"&gt;ESCAPED_ENTITIES_MAP&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;html_escape&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sx"&gt;%Q(&amp;lt;a href="link.html?a&amp;amp;b"&amp;gt;text&amp;lt;/a&amp;gt;)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "&amp;amp;lt;a href=&amp;amp;quot;link.html?a&amp;amp;amp;b&amp;amp;quot;&amp;amp;gt;text&amp;amp;lt;/a&amp;amp;gt;"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Useful to know that exists, anyways, back on topic.&lt;/p&gt;

&lt;p&gt;The book then mentions a few Rails concepts, the inflector and the pluralizer. It's used to determine that the class inside &lt;code&gt;current_employee.rb&lt;/code&gt; should be &lt;code&gt;CurrentEmployee&lt;/code&gt;, and the associated DB table should be &lt;code&gt;current_employee&lt;/code&gt;. As the book mentions this is done with &lt;code&gt;String&lt;/code&gt; processing.&lt;/p&gt;

&lt;p&gt;It works via a set of rules, especially around pluralization, like irregular pluralization cases like &lt;code&gt;person&lt;/code&gt; pluralizing into &lt;code&gt;people&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;irregular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"person"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"people"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;irregular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"man"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"men"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;irregular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"child"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"children"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;inflect&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;irregular&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;"sex"&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"sexes"&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which are applied via &lt;code&gt;gsub!&lt;/code&gt;, which uses that behavior of returning &lt;code&gt;nil&lt;/code&gt; mentioned above:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;inflections&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;plurals&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;break&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;rule&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;replacement&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now one could probably do this with &lt;code&gt;find&lt;/code&gt; instead and avoid mutations, but knowing Rails and some of the optimization cases there there's probably a reason for it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Staying Out of Trouble
&lt;/h3&gt;

&lt;p&gt;Ruby &lt;code&gt;String&lt;/code&gt;s are mutable. There are ways around this with &lt;code&gt;freeze&lt;/code&gt; and the frozen string literal:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# frozen_string_literal: true&lt;/span&gt;

&lt;span class="s2"&gt;"string"&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;freeze&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That means that any of those bang methods from above will mutate the underlying &lt;code&gt;String&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;first_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Susan"&lt;/span&gt;
&lt;span class="n"&gt;given_name&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;first_name&lt;/span&gt;

&lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="o"&gt;..-&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"ie"&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "ie"&lt;/span&gt;

&lt;span class="n"&gt;first_name&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "Susie"&lt;/span&gt;

&lt;span class="n"&gt;given_name&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "Susie"&lt;/span&gt;

&lt;span class="n"&gt;first_name&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase!&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "susie"&lt;/span&gt;

&lt;span class="n"&gt;first_name&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "susie"&lt;/span&gt;

&lt;span class="n"&gt;given_name&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; "susie"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So be careful when mutating things unless you really really need it, but most of the time? You won't.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;This wraps up chapter 4, which covers a lot of &lt;code&gt;String&lt;/code&gt;s in Ruby, but leaves some of the real interesting parts for chapter 5 where we get into Regex.&lt;/p&gt;

&lt;p&gt;In the mean time? The book is correct, &lt;code&gt;String&lt;/code&gt;s are exceptionally common in Ruby, and dealing with them is going to be a substantial part of what you do in Ruby. Getting comfortable with those docs is certainly a wise investment.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
      <category>books</category>
    </item>
    <item>
      <title>Ruby 3.1 – Shorthand Hash Syntax – First Impressions</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Sun, 12 Sep 2021 05:09:51 +0000</pubDate>
      <link>https://dev.to/baweaver/ruby-3-1-shorthand-hash-syntax-first-impressions-19op</link>
      <guid>https://dev.to/baweaver/ruby-3-1-shorthand-hash-syntax-first-impressions-19op</guid>
      <description>&lt;p&gt;It's the time of year again, and with it comes a bundle of new Ruby 3.1 features getting approved and merged ahead of the December release.&lt;/p&gt;

&lt;p&gt;This series will be covering a few of the interesting ones I see going across the bug tracker. Have one you think is interesting? Send it my way on Twitter @keystonelemur or comment here.&lt;/p&gt;

&lt;h2&gt;
  
  
  Shorthand Hash Syntax - First Impressions
&lt;/h2&gt;

&lt;p&gt;Now this, this is something I've wanted for a very long time. Shorthand Hash Syntax, also known as Punning in Javascript, is an incredibly useful feature that allows you to omit values where the variable name is the same as the key:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;b: &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; { a: 1, b: 2 }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In Javascript this would like like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight javascript"&gt;&lt;code&gt;&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="kd"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nx"&gt;b&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;So you can see some of the resemblance between the two.&lt;/p&gt;

&lt;h3&gt;
  
  
  Commits and Tracker
&lt;/h3&gt;

&lt;p&gt;You can find the &lt;a href="https://github.com/ruby/ruby/commit/c60dbcd1c55cd77a24c41d5e1a9555622be8b2b8#diff-f43e8aa2106104930c9b21126ca95cd572e25630b0e5d0bffe720a21da34771aR2182"&gt;relevant diff here&lt;/a&gt; and the &lt;a href="https://bugs.ruby-lang.org/issues/14579"&gt;bugtracker issue here&lt;/a&gt;.&lt;/p&gt;

&lt;h2&gt;
  
  
  Exploring the Testcases
&lt;/h2&gt;

&lt;p&gt;Let's take a look into the specs from that diff (slightly abbreviated):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;test_value_omission&lt;/span&gt;
  &lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

  &lt;span class="n"&gt;assert_equal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:})&lt;/span&gt;
  &lt;span class="n"&gt;assert_equal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;one: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;two: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt;&lt;span class="p"&gt;:})&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now as mentioned before, this allows value omission as specified in the first assertion:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;x&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

&lt;span class="n"&gt;assert_equal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt;&lt;span class="p"&gt;:})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This is what I would expect the feature to do, and already opens up a lot of potential which I'll get into in a moment, but there's something else here in the second:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;assert_equal&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt;&lt;span class="ss"&gt;one: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;two: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="n"&gt;one&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;two&lt;/span&gt;&lt;span class="p"&gt;:})&lt;/span&gt;

&lt;span class="c1"&gt;# ...&lt;/span&gt;

&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;one&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;two&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...it's also working on methods, which opens up a whole new realm of interesting potential. I'll be breaking these into two sections to address what I think the implications of each are.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implications of Punning
&lt;/h2&gt;

&lt;p&gt;Let's start with general implications, as I believe those alone are interesting enough to write on. &lt;/p&gt;

&lt;h3&gt;
  
  
  Pattern Matching
&lt;/h3&gt;

&lt;p&gt;Consider with me pattern matching:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;x: &lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# I do still wish `y` was captured here without right-hand assignment&lt;/span&gt;
&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="k"&gt;then&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;x&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;y: &lt;/span&gt;&lt;span class="n"&gt;y&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This allows us to abbreviate the idea of leaving one value unchanged, and working with another value explicitly. In another case with a JSON response we might want to extract a few fields while changing one:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;case&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;
&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="ss"&gt;code: &lt;/span&gt;&lt;span class="mi"&gt;200&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;people: &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;messages&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;people: &lt;/span&gt;&lt;span class="n"&gt;people&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="no"&gt;Person&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="ss"&gt;code: &lt;/span&gt;&lt;span class="mi"&gt;400&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;body: &lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;stacktrace: &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;error&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;stacktrace: &lt;/span&gt;&lt;span class="n"&gt;stacktrace&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# ...&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It allows us to be more succinct in what we're simply extracting and what we're transforming.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; I have not tried combining this with regular &lt;code&gt;Hash&lt;/code&gt; syntax, but I assume this will work given the &lt;code&gt;parse.y&lt;/code&gt; code. More experimentation needed.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Keyword Arguments
&lt;/h3&gt;

&lt;p&gt;Keyword arguments in general are a huge value-add to Ruby for understandability and errors:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# (A tinge contrived, yes)&lt;/span&gt;
&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;json_logger&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;limit: &lt;/span&gt;&lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;new_message&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;limit&lt;/span&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;first&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;limit&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;message&lt;/span&gt;
  &lt;span class="no"&gt;Logger&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;log&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="ss"&gt;level: &lt;/span&gt;&lt;span class="n"&gt;level&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;message: &lt;/span&gt;&lt;span class="n"&gt;new_message&lt;/span&gt; &lt;span class="p"&gt;}.&lt;/span&gt;&lt;span class="nf"&gt;to_json&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;With one argument that's not too bad, but the biggest annoyance of keyword arguments is constantly doing this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;a: &lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;b: &lt;/span&gt;&lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;c: &lt;/span&gt;&lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;d: &lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It feels repetitive and doesn't add extra value. Punning in JS elided this information into arguments which should be forwarded without transformation, and Ruby shorthand hash syntax does the same. The benefits of keyword arguments without all of the extra code:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;some_method&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;d: &lt;/span&gt;&lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now we can quickly see only &lt;code&gt;d&lt;/code&gt; is being modified, allowing us to more clearly see the intent of the code, while also getting all of the benefits of keyword arguments around name checks, value checks, and more easily understood methods.&lt;/p&gt;

&lt;p&gt;I see this being the highest value add.&lt;/p&gt;

&lt;h2&gt;
  
  
  Implications of Including Methods
&lt;/h2&gt;

&lt;p&gt;This one is a bit more unusual, but I like the idea.&lt;/p&gt;

&lt;h3&gt;
  
  
  Configuration Hashes
&lt;/h3&gt;

&lt;p&gt;There are a lot of cases where I have to assemble larger hashes of configuration. By putting parts of it into methods I've made it easier to manage:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;configuration&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;c: &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;b&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="kp"&gt;private&lt;/span&gt; &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those could be things like say logger configs, AWS keys, library configuration, and very interestingly (and I don't know if this would work) optional configuration cascades:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;configuration&lt;/span&gt;
  &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="n"&gt;logger&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;stack_limit&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;tracing: &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;logging&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;enabled?&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="n"&gt;shards&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="n"&gt;rw&lt;/span&gt;&lt;span class="p"&gt;:,&lt;/span&gt; &lt;span class="ss"&gt;clusters: &lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;db&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sharded?&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
    &lt;span class="c1"&gt;# ...&lt;/span&gt;
  &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Of course those are theoretical and I would need to spend substantial time with this feature after nightly builds are out to be sure on this, but if it does work it opens the door for some very interesting cascading configuration styles in the future.&lt;/p&gt;

&lt;h2&gt;
  
  
  Wrap Up
&lt;/h2&gt;

&lt;p&gt;This is a first impressions article on the shorthand hash syntax, and I expect as I have time to play with it I'll come up with some new ideas. Until then, I'll be watching the bug tracker for fun new features coming up soon.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>rails</category>
    </item>
    <item>
      <title>Let's Read – Eloquent Ruby – Ch 3</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Tue, 07 Sep 2021 07:01:59 +0000</pubDate>
      <link>https://dev.to/baweaver/let-s-read-eloquent-ruby-ch-3-57np</link>
      <guid>https://dev.to/baweaver/let-s-read-eloquent-ruby-ch-3-57np</guid>
      <description>&lt;p&gt;Perhaps my personal favorite recommendation for learning to program Ruby like a Rubyist, &lt;a href="http://eloquentruby.com/"&gt;Eloquent Ruby&lt;/a&gt; is a book I recommend frequently to this day. That said, it was released in 2011 and things have changed a bit since then.&lt;/p&gt;

&lt;p&gt;This series will focus on reading over Eloquent Ruby, noting things that may have changed or been updated since 2011 (around Ruby 1.9.2) to today (2021 — Ruby 3.0.x).&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: This is an updated version of a previous unfinished Medium series of mine you can &lt;a href="https://medium.com/@baweaver/lets-read-eloquent-ruby-ch-1-b2115d1416a6"&gt;find here&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h2&gt;
  
  
  Chapter 3. Take Advantage of Ruby's Smart Collections
&lt;/h2&gt;

&lt;p&gt;This chapter covers some of Ruby's collection classes and how to work with them. In Ruby this is probably going to be one of your most powerful and often used sets of libraries and features to work with, and in my early days I frequently found myself consulting this chapter and all the documentation related to it.&lt;/p&gt;

&lt;p&gt;The book mentions here that if you were to look into any well-sized Ruby program you're going to find a ton of &lt;code&gt;Array&lt;/code&gt;s and &lt;code&gt;Hash&lt;/code&gt;es scattered throughout, and all of the operations that occur on them. I've found this to be exceptionally true, and as mentioned above it's one of the most powerful parts of the language.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Enumerable&lt;/code&gt;'s documentation is going to get a lot of reference as you learn Ruby and become more effective in it.&lt;/p&gt;

&lt;h3&gt;
  
  
  Literal Shortcuts
&lt;/h3&gt;

&lt;p&gt;The book mentions a few ways of constructing an &lt;code&gt;Array&lt;/code&gt; to start with:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# The normal way&lt;/span&gt;
&lt;span class="n"&gt;poem_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s1"&gt;'twinkle'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'little'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'star'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'how'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'I'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'wonder'&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="c1"&gt;# Whitespace delimited words, same as the above&lt;/span&gt;
&lt;span class="n"&gt;poem_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w{twinkle little star how I wonder}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now one qualm I have with the book here is that &lt;code&gt;{}&lt;/code&gt; can be confused with &lt;code&gt;Hash&lt;/code&gt; later, and you're more likely to find common usage of either &lt;code&gt;%w()&lt;/code&gt; or &lt;code&gt;%w[]&lt;/code&gt; in its place. There are others, but by that point it's becoming a bit ridiculous. Personally I prefer &lt;code&gt;%w()&lt;/code&gt;, but can see why the other is popular:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;poem_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w(twinkle little star how I wonder)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The next bit covers &lt;code&gt;Hash&lt;/code&gt;es, and the hash rocket (&lt;code&gt;=&amp;gt;&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;freq&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s2"&gt;"I"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"don't"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"like"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;"spam"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="mi"&gt;963&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For &lt;code&gt;String&lt;/code&gt; keys you'll find that in common use, but &lt;code&gt;Symbol&lt;/code&gt; keys are a bit different:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;book_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;:first_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Russ'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:last_name&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s1"&gt;'Olsen'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;book_info&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;first_name: &lt;/span&gt;&lt;span class="s1"&gt;'Russ'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;last_name: &lt;/span&gt;&lt;span class="s1"&gt;'Olsen'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;They produce the same &lt;code&gt;Hash&lt;/code&gt;, but one uses the &lt;code&gt;1.9.x&lt;/code&gt; "JSON-style" syntax. Very likely that syntax will look familiar as you find keyword arguments in methods as well, and it's generally preferred.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Personal Hill&lt;/strong&gt;: Granted I really wish that &lt;code&gt;Symbol&lt;/code&gt; keys would just be translated to &lt;code&gt;String&lt;/code&gt; as this causes a lot of confusion for newer programmers for little gain, especially now that &lt;code&gt;String&lt;/code&gt;s are so commonly frozen. As always when I mention this I acknowledge there's 0% chance this changes, but I still find it a particularly frustrating part of Ruby.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Instant &lt;code&gt;Array&lt;/code&gt;s and &lt;code&gt;Hash&lt;/code&gt;es from Method Calls
&lt;/h3&gt;

&lt;p&gt;The book goes on to mention ways of getting an &lt;code&gt;Array&lt;/code&gt; or a &lt;code&gt;Hash&lt;/code&gt; from a method call, in what is called a "splat" (&lt;code&gt;*&lt;/code&gt;) or "keyword/hash splat" (&lt;code&gt;**&lt;/code&gt;):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;echo_all&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;arg&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;echo_at_least_two&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;first_arg&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;middle_args&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;last_arg&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"The first argument is &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;first_arg&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="n"&gt;middle_args&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"A middle argument is &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;arg&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"The last argument is &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;last_arg&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Wherein the first is called a "varadic" method taking any number of arguments, and the second is much the same except that splat can be anywhere in the list. You can also do this on assignments:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# a = 1, bs = [2, 3]&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;bs&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="c1"&gt;# a = 1, bs = [2], c = 3&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book then goes on to mention explicit versus implicit &lt;code&gt;Array&lt;/code&gt;s:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_authors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;add_authors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@author&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="s2"&gt;" &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;' '&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In the first case it would need to be called as such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_authors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sx"&gt;%w(Jemisin Schwab)&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but the second might be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;document&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;add_authors&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'Le Guin'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'Hobb'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;(Note that Ursula Le Guin would break that code's space delimiter, how might you fix it?)&lt;/p&gt;

&lt;p&gt;The book then goes into a similar section on &lt;code&gt;Hash&lt;/code&gt;es with &lt;code&gt;load_font&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;specification_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# details omitted&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;load_font&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Helvetica'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;size: &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we happened to use the double-splat (or keyword splat, hash splat, or other names):&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;load_font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;**&lt;/span&gt;&lt;span class="n"&gt;specification_hash&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="c1"&gt;# details omitted&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;load_font&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="ss"&gt;name: &lt;/span&gt;&lt;span class="s1"&gt;'Helvetica'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;size: &lt;/span&gt;&lt;span class="mi"&gt;12&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Warning&lt;/strong&gt;: The book mentions that you can omit braces in the first case, but with Ruby 3.x+ this becomes complicated and is not recommended. Prefer to be explicit, and give the &lt;a href="https://eregon.me/blog/2021/02/13/correct-delegation-in-ruby-2-27-3.html"&gt;Ruby 2 Keyword Argument conundrum a read&lt;/a&gt;.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3&gt;
  
  
  Running Through Your Collection
&lt;/h3&gt;

&lt;p&gt;The book starts with a &lt;code&gt;for&lt;/code&gt; loop example it quickly discourages afterwards:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="sx"&gt;%w(Mary had a little lamb)&lt;/span&gt;

&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="o"&gt;..&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Though I think this is a more common variant to folks:&lt;/span&gt;
&lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If you really want to know why you should avoid &lt;code&gt;for&lt;/code&gt; in detail beyond "just use &lt;code&gt;each&lt;/code&gt;" give &lt;a href="https://dev.to/baweaver/understanding-ruby-for-vs-each-47ae"&gt;this post a read&lt;/a&gt;, or just take our word for it on using &lt;code&gt;each&lt;/code&gt; instead. The &lt;code&gt;each&lt;/code&gt; variant of that code would be:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the book mentions &lt;code&gt;Hash&lt;/code&gt;es also have an &lt;code&gt;each&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;movie&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="ss"&gt;title: &lt;/span&gt;&lt;span class="s1"&gt;'2001'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;genre: &lt;/span&gt;&lt;span class="s1"&gt;'sci fi'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
  &lt;span class="ss"&gt;rating: &lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="c1"&gt;# Single-argument yields the key and value as an Array&lt;/span&gt;
&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# [:title, "2001"]&lt;/span&gt;
&lt;span class="c1"&gt;# [:genre, 'sci fi']&lt;/span&gt;
&lt;span class="c1"&gt;# [:rating, 10]&lt;/span&gt;

&lt;span class="c1"&gt;# This allows access to the key and the value:&lt;/span&gt;
&lt;span class="n"&gt;movie&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="nb"&gt;name&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt; =&amp;gt; &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# title =&amp;gt; 2001&lt;/span&gt;
&lt;span class="c1"&gt;# genre =&amp;gt; sci fi&lt;/span&gt;
&lt;span class="c1"&gt;# rating =&amp;gt; 10&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: The book likes to use &lt;code&gt;pp&lt;/code&gt; without mentioning it. It stands for &lt;a href="https://ruby-doc.org/stdlib-3.0.2/libdoc/pp/rdoc/PP.html"&gt;Pretty Print&lt;/a&gt;, which is not really useful for most of the cases in this chapter, but can be for larger collections when you want it to be readable rather than a single-line you have to scroll to get through.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now after this the book starts dropping hints for &lt;code&gt;Enumerable&lt;/code&gt; and all the handy methods in it. Consider this, a potential method for finding the index of a word in a document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
  &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;this_word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;this_word&lt;/span&gt;
    &lt;span class="n"&gt;i&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="kp"&gt;nil&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Ruby has a lovely method which already takes care of this called &lt;code&gt;find_index&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;this_word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;this_word&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now I do have some slight qualms with the naming here, as &lt;code&gt;word&lt;/code&gt; would be better as the iterated variable, and &lt;code&gt;this_word&lt;/code&gt; could be the argument instead and renamed to &lt;code&gt;target_word&lt;/code&gt; for intent, making this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;index_for&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;target_word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
  &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;find_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="n"&gt;target_word&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which personally I find a bit easier to read at a glance for a few reasons:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;
&lt;code&gt;target_word&lt;/code&gt; makes the searched word more distinct than &lt;code&gt;word&lt;/code&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;word&lt;/code&gt; is more suited to the generic word in a collection&lt;/li&gt;
&lt;li&gt;Shifting &lt;code&gt;word&lt;/code&gt; to the left gives it proximity to the block argument, making it easier to read left-to-right.&lt;/li&gt;
&lt;/ol&gt;

&lt;p&gt;Now that last one is interesting, and will come up again in later sections. Proximity, and left-to-right, are very important in general readability of code and should be kept in mind. Names equally so.&lt;/p&gt;

&lt;p&gt;If we had &lt;code&gt;word&lt;/code&gt; at the end our eye has to go to the right to find where it's used, then back left to find what it's being compared to. Because &lt;code&gt;word&lt;/code&gt; is more proximate to that scope it reads better when put first in that block.&lt;/p&gt;

&lt;p&gt;I find this to be something I tend to do without thinking of it, but it has made code a lot easier to read at a glance and reduce jumping.&lt;/p&gt;

&lt;p&gt;Anyways, back to the book, where we take a look into &lt;code&gt;map&lt;/code&gt; which returns a new &lt;code&gt;Array&lt;/code&gt; transformed by a block function:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [2, 4 , 6]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book uses this example of a hypothetical document, which I find a bit less clear for building immediate intuition:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [3, 5, 2, 3, 4]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and a way to lowercase all of those words:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;lower_case_words&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;doc&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;map&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;downcase&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It then goes into &lt;code&gt;inject&lt;/code&gt; which I'll be using &lt;code&gt;reduce&lt;/code&gt; instead as you'll find it more commonly in other languages (also &lt;code&gt;foldLeft&lt;/code&gt; which isn't present in Ruby, but &lt;em&gt;does&lt;/em&gt; more clearly articulate the function of the method).&lt;/p&gt;

&lt;p&gt;The example the book uses is finding the average word length in a document:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;
  &lt;span class="c1"&gt;# The initial case, and the way you might approach it&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;average_word_length&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mf"&gt;0.0&lt;/span&gt;
    &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;word_count&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="c1"&gt;# The same done with reduce&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;average_word_length&lt;/span&gt;
    &lt;span class="c1"&gt;# Yes, I swapped the order here to put result first&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mf"&gt;0.0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;result&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;result&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;size&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
    &lt;span class="n"&gt;total&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="n"&gt;word_count&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now that's a bit hard to understand if you've never seen &lt;code&gt;reduce&lt;/code&gt; before, so try this example real quick:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;reduce&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="ss"&gt;accumulator: &lt;/span&gt;&lt;span class="n"&gt;accumulator&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;v: &lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;new_accumulator: &lt;/span&gt;&lt;span class="n"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
  &lt;span class="n"&gt;accumulator&lt;/span&gt; &lt;span class="o"&gt;+&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="c1"&gt;# {:accumulator=&amp;gt;0, :v=&amp;gt;1, :new_accumulator=&amp;gt;1}&lt;/span&gt;
&lt;span class="c1"&gt;# {:accumulator=&amp;gt;1, :v=&amp;gt;2, :new_accumulator=&amp;gt;3}&lt;/span&gt;
&lt;span class="c1"&gt;# {:accumulator=&amp;gt;3, :v=&amp;gt;3, :new_accumulator=&amp;gt;6}&lt;/span&gt;
&lt;span class="c1"&gt;#  =&amp;gt; 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea is that &lt;code&gt;reduce&lt;/code&gt; is reducing a collection of items into one item, in this case a number &lt;code&gt;0&lt;/code&gt;. &lt;code&gt;accumulator&lt;/code&gt; starts as &lt;code&gt;0&lt;/code&gt;, and each loop becomes the value returned from the block function as we see in &lt;code&gt;new_accumulator&lt;/code&gt; before the next loop. Whatever the value of the &lt;code&gt;accumulator&lt;/code&gt; is at the end is the value we get returned.&lt;/p&gt;

&lt;p&gt;If you want to read more into &lt;code&gt;reduce&lt;/code&gt; &lt;a href="https://dev.to/baweaver/understanding-ruby-enumerable-combining-58eo"&gt;take a look at this article&lt;/a&gt; where I explain it in more detail, and a &lt;a href="https://www.youtube.com/watch?v=x3b9KlzjJNM"&gt;conference talk I did called Reducing Enumerable&lt;/a&gt; which goes into far more detail.&lt;/p&gt;

&lt;p&gt;Now that all said Ruby 2.4 introduced a method called &lt;code&gt;sum&lt;/code&gt; which makes all of this much easier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; 6&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which makes that above document method look more like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;Document&lt;/span&gt;
  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;average_word_length&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;sum&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="ss"&gt;:size&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nf"&gt;fdiv&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word_count&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;How's that for succinct? See &lt;a href="https://dev.to/baweaver/understanding-ruby-blocks-procs-and-lambdas-24o0"&gt;this post&lt;/a&gt; and search for Ampersand (&lt;code&gt;&amp;amp;&lt;/code&gt;) and &lt;code&gt;to_proc&lt;/code&gt; for more information on that shorthand.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Note&lt;/strong&gt;: &lt;code&gt;fdiv&lt;/code&gt; is float division, which is more explicit than using &lt;code&gt;0.0&lt;/code&gt; for an accumulator, or converting one of the values to a float.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;There are still uses for &lt;code&gt;reduce&lt;/code&gt;, sure, but I find they're rather rare and normally there are clearer methods to use in &lt;code&gt;Enumerable&lt;/code&gt; you should consider first. That said, it's also exceptionally powerful and you could quite literally reimplement every other &lt;code&gt;Enumerable&lt;/code&gt; method with &lt;code&gt;reduce&lt;/code&gt; as well.&lt;/p&gt;

&lt;p&gt;Chainsaws for trimming bonsai trees and such, use the least amount of power you need to get something done, and appearing clever surely isn't a valid reason to reach for a more powerful tool. Readability first, remember that one, it'll save you nightmares later.&lt;/p&gt;

&lt;h3&gt;
  
  
  Beware the Bang!
&lt;/h3&gt;

&lt;p&gt;In Ruby a bang (ending with &lt;code&gt;!&lt;/code&gt;) method is usually a warning sign, often related to a method mutating something or having some other side effect. Let's take a look at the book's example on &lt;code&gt;reverse&lt;/code&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;1&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [3, 2, 1]&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [1, 2, 3]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This version returns a new &lt;code&gt;Array&lt;/code&gt; without mutating the old one, but the bang method?&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [1, 2, 3]&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reverse!&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [3, 2, 1]&lt;/span&gt;
&lt;span class="n"&gt;a&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [3, 2, 1]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It mutates &lt;code&gt;a&lt;/code&gt;. As an aside, Javascript's &lt;code&gt;reverse&lt;/code&gt; totally mutates an &lt;code&gt;Array&lt;/code&gt;, ask me sometime why I know...&lt;/p&gt;

&lt;p&gt;The book mentions that &lt;code&gt;sort&lt;/code&gt; and &lt;code&gt;sort!&lt;/code&gt; behave similarly, but makes the lovely followup that methods like &lt;code&gt;push&lt;/code&gt;, &lt;code&gt;pop&lt;/code&gt;, &lt;code&gt;delete&lt;/code&gt;, and &lt;code&gt;shift&lt;/code&gt; also modify an &lt;code&gt;Array&lt;/code&gt; too without a bang.&lt;/p&gt;

&lt;p&gt;It mentions several methods may mutate things, so there's not always consistency here and it's best to be aware. Bang methods also tend to return &lt;code&gt;nil&lt;/code&gt; in some cases when something does not change:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;s&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'string'&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/b/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; 'string'&lt;/span&gt;
&lt;span class="n"&gt;s&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;gsub!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="sr"&gt;/b/&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;'c'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; nil&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...meaning you can't chain things. They're faster, sure, but you trade a lot of what makes Ruby chaining so nice by doing so.&lt;/p&gt;

&lt;h3&gt;
  
  
  Rely on the Order of Your &lt;code&gt;Hash&lt;/code&gt;es
&lt;/h3&gt;

&lt;p&gt;In the next section it mentions something which can be very useful, but very different from other languages:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Hash&lt;/code&gt;es in Ruby retain insertion order.&lt;/p&gt;

&lt;p&gt;That means running this code does this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;hey_its_ordered&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="ss"&gt;first: &lt;/span&gt;&lt;span class="s1"&gt;'mama'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;second: &lt;/span&gt;&lt;span class="s1"&gt;'papa'&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;third: &lt;/span&gt;&lt;span class="s1"&gt;'baby'&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;hey_its_ordered&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;entry&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;entry&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="c1"&gt;# [:first, 'mama']&lt;/span&gt;
&lt;span class="c1"&gt;# [:second, 'papa']&lt;/span&gt;
&lt;span class="c1"&gt;# [:third, 'baby']&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and adding one more element:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;hey_its_ordered&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:fourth&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s1"&gt;'grandma'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...puts it at the end. The book also mentions that changing an existing element does not reorder things.&lt;/p&gt;

&lt;p&gt;This section hasn't really changed much if at all from Ruby 1.9, so there's not much to comment on here.&lt;/p&gt;

&lt;h3&gt;
  
  
  In the Wild
&lt;/h3&gt;

&lt;p&gt;The book then goes into a few examples. The first examples are mainly covering class-methods which don't return an instance, but rather a collection. A few of those examples:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;File&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;readlines&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'/etc/passwd'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;object&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;public_methods&lt;/span&gt;
&lt;span class="n"&gt;my_class&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;ancestors&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Those types of methods tend to be common where Ruby will return a collection or other appropriate type, but the next example is a little clearer where generic collections really come in handy as a return type.&lt;/p&gt;

&lt;p&gt;Let's take this XML:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight xml"&gt;&lt;code&gt;&lt;span class="nt"&gt;&amp;lt;characters&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;super-hero&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Spiderman&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;origin&amp;gt;&lt;/span&gt;Radioactive Spider&lt;span class="nt"&gt;&amp;lt;/origin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/super-hero&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;super-hero&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Hulk&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;origin&amp;gt;&lt;/span&gt;Gamma Rays&lt;span class="nt"&gt;&amp;lt;/origin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/super-hero&amp;gt;&lt;/span&gt;

  &lt;span class="nt"&gt;&amp;lt;super-hero&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;name&amp;gt;&lt;/span&gt;Reed Richards&lt;span class="nt"&gt;&amp;lt;/name&amp;gt;&lt;/span&gt;
    &lt;span class="nt"&gt;&amp;lt;origin&amp;gt;&lt;/span&gt;Cosmic Rays&lt;span class="nt"&gt;&amp;lt;/origin&amp;gt;&lt;/span&gt;
  &lt;span class="nt"&gt;&amp;lt;/super-hero&amp;gt;&lt;/span&gt;
&lt;span class="nt"&gt;&amp;lt;/characters&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;If we were to parse that into Ruby we'd get something like this:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'xmlsimple'&lt;/span&gt;
&lt;span class="n"&gt;data&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;XmlSimple&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;xml_in&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;'dc.xml'&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="c1"&gt;# Returns:&lt;/span&gt;
&lt;span class="p"&gt;{&lt;/span&gt;
  &lt;span class="s2"&gt;"super-hero"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Spiderman"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"origin"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Radioactive Spider"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Hulk"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"origin"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Gamma Rays"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;},&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
    &lt;span class="s2"&gt;"name"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Reed"&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
    &lt;span class="s2"&gt;"origin"&lt;/span&gt; &lt;span class="o"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;"Cosmic Rays"&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="p"&gt;}]&lt;/span&gt;
&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It's really something just how much you can express with &lt;code&gt;Hash&lt;/code&gt;es and &lt;code&gt;Array&lt;/code&gt;s in Ruby, and very frequently (and admittedly not always a great idea) I tend to avoid classes in favor of them until I get a tangible benefit from abstracting that data into a class wrapper.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;Array&lt;/code&gt;s and &lt;code&gt;Hash&lt;/code&gt;es are simple to work with, have known interfaces, and don't require additional effort beyond language knowledge to use effectively.&lt;/p&gt;

&lt;h3&gt;
  
  
  Staying Out of Trouble
&lt;/h3&gt;

&lt;p&gt;The book warns about manipulating a collection you're currently iterating on. In one case it's not a great idea to mutate state, but mutating the state of something that's currently in use like iteration? That's just asking for problems and errors.&lt;/p&gt;

&lt;p&gt;Consider the book's example here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="o"&gt;-&lt;/span&gt;&lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;9&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each_index&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;delete_at&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;span class="n"&gt;pp&lt;/span&gt; &lt;span class="n"&gt;array&lt;/span&gt;
&lt;span class="c1"&gt;# =&amp;gt; [0, -9, 5, 9]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;It skips &lt;code&gt;-9&lt;/code&gt; because the element at that index just shifted with the deleted element.&lt;/p&gt;

&lt;p&gt;The book then mentions making large &lt;code&gt;Array&lt;/code&gt;s inadvertently like so:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;24601&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="s2"&gt;"Jean Valjean"&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...being a reference to Les Miserables, but every element up to &lt;code&gt;24601&lt;/code&gt; is now &lt;code&gt;nil&lt;/code&gt; and that's not free in terms of memory.&lt;/p&gt;

&lt;p&gt;The next example the book gets into is a unique list of words using a few different methods:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;word_is_there&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;{}&lt;/span&gt;
&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;word_is_there&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;

&lt;span class="n"&gt;unique&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;word&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;unique&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;include?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;word&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second being much much slower as it has to iterate that &lt;code&gt;unique&lt;/code&gt; list multiple times to find if a word is unique. &lt;code&gt;Hash&lt;/code&gt;es have a lookup time of &lt;code&gt;O(1)&lt;/code&gt;, whereas &lt;code&gt;Array&lt;/code&gt;s are more of an &lt;code&gt;O(n)&lt;/code&gt; lookup time.&lt;/p&gt;

&lt;p&gt;While one can use the Hash case for this, &lt;code&gt;Set&lt;/code&gt; is easier:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;require&lt;/span&gt; &lt;span class="s1"&gt;'set'&lt;/span&gt;
&lt;span class="n"&gt;word_set&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Set&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...or get into &lt;code&gt;Enumerable&lt;/code&gt; and find the &lt;code&gt;uniq&lt;/code&gt; method:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;words&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;uniq&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...which encapsulates the entire idea quite nicely without the extra work.&lt;/p&gt;

&lt;h3&gt;
  
  
  Wrapping Up
&lt;/h3&gt;

&lt;p&gt;In Ruby chances are real high you're going to encounter collections, so knowing what they are and how they're used is a massive boost in your early productivity for both reading and writing.&lt;/p&gt;

&lt;p&gt;Over the years Ruby has added a lot of &lt;code&gt;Enumerable&lt;/code&gt;, Pattern Matching, and other features which make dealing with collections much easier. Later chapters will cover this, but that shouldn't stop you from taking a glance at a few in the docs.&lt;/p&gt;

&lt;p&gt;The next chapter covers &lt;code&gt;String&lt;/code&gt;s, which will be the other most likely candidate for things you'll encounter and have to work with in Ruby.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>books</category>
    </item>
    <item>
      <title>Let's Read – Polished Ruby Programming – Ch 3.1 – Local Variables</title>
      <dc:creator>Brandon Weaver</dc:creator>
      <pubDate>Mon, 30 Aug 2021 06:19:51 +0000</pubDate>
      <link>https://dev.to/baweaver/polished-ruby-programming-ch-3-1-local-variables-1861</link>
      <guid>https://dev.to/baweaver/polished-ruby-programming-ch-3-1-local-variables-1861</guid>
      <description>&lt;p&gt;&lt;a href="https://www.packtpub.com/product/polished-ruby-programming/9781801072724"&gt;Polished Ruby Programming&lt;/a&gt; is a recent release by &lt;a href="https://twitter.com/jeremyevans0"&gt;Jeremy Evans&lt;/a&gt;, a well known Rubyist working on the Ruby core team, Roda, Sequel, and several other projects. Knowing Jeremy and his experience this was an instant buy for me, and I look forward to what we learn in this book.&lt;/p&gt;

&lt;p&gt;You can find the book here:&lt;/p&gt;

&lt;p&gt;&lt;a href="https://www.packtpub.com/product/polished-ruby-programming/9781801072724"&gt;https://www.packtpub.com/product/polished-ruby-programming/9781801072724&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;This review, like other "Let's Read" series in the past, will go through each of the chapters individually and will add commentary, additional notes, and general thoughts on the content. Do remember books are limited in how much information they can cram on a page, and they can't cover everything.&lt;/p&gt;

&lt;p&gt;With that said let's go ahead and get started.&lt;/p&gt;

&lt;h2&gt;
  
  
  Chapter 3 – Proper Variable Usage – Local Variables
&lt;/h2&gt;

&lt;p&gt;The third chapter covers the following topics:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Using Ruby's favorite variable type – the local variable

&lt;ul&gt;
&lt;li&gt;Increasing performance by adding local variables&lt;/li&gt;
&lt;li&gt;Avoiding unsafe optimizations&lt;/li&gt;
&lt;li&gt;Handling scope gate issues&lt;/li&gt;
&lt;li&gt;Naming considerations with local variables&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Learning how best to use instance variables

&lt;ul&gt;
&lt;li&gt;Increasing performance with instance variables&lt;/li&gt;
&lt;li&gt;Handling scope issues with instance variables&lt;/li&gt;
&lt;li&gt;Naming considerations for instance variables&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Understanding how constants are just a type of variable

&lt;ul&gt;
&lt;li&gt;Handling scope issues with constants&lt;/li&gt;
&lt;li&gt;Visibility differences between constants and class instance variables&lt;/li&gt;
&lt;li&gt;Naming considerations with constants&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Replacing class variables

&lt;ul&gt;
&lt;li&gt;Replacing class variables with constants&lt;/li&gt;
&lt;li&gt;Replacing class variables with class instance variables using the superclass lookup approach&lt;/li&gt;
&lt;li&gt;Replacing class variables with class instance variables using the copy to subclass approach&lt;/li&gt;
&lt;/ul&gt;


&lt;/li&gt;
&lt;li&gt;Avoiding global variables, most of the time&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll be covering the first section on local variables to make this chapter's post more digestible.&lt;/p&gt;

&lt;h3&gt;
  
  
  Using Ruby's favorite variable type – the local variable
&lt;/h3&gt;

&lt;p&gt;The chapter starts in by explaining local variables in Ruby, and mentions they're the only type without a sigil. For a quick list here are a few you might find later:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;
&lt;code&gt;@variable&lt;/code&gt; - Instance variable&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;@@variable&lt;/code&gt; - Class variable (generally avoid)&lt;/li&gt;
&lt;li&gt;
&lt;code&gt;$variable&lt;/code&gt; - Global variable (generally avoid)&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;We'll get into some of the issues with the latter two, as does the book, but for now we'll focus on local variables along with the book.&lt;/p&gt;

&lt;h4&gt;
  
  
  Increasing performance by adding local variables
&lt;/h4&gt;

&lt;p&gt;Local variables are fast. The book mentions this, and most of the reason behind it comes from less indirection as previous chapters have mentioned. On the low level that means they're also more likely to be in the CPU cache.&lt;/p&gt;

&lt;p&gt;The book opens with this code example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;time_filter&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TimeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
  &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;10&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
  &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;local&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="mi"&gt;2020&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="mi"&gt;11&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="p"&gt;)&lt;/span&gt;

&lt;span class="n"&gt;array_of_times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;filter!&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;time_filter&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; - I dislike hanging indent, so I avoid it. You can read more into that &lt;a href="https://github.com/rubocop/ruby-style-guide/issues/359"&gt;here&lt;/a&gt;, but the short version is harder to maintain, longer diffs, and far harder to read with long-lines. Whitespace is free, use it.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Now the stated purpose of &lt;code&gt;TimeFilter&lt;/code&gt; here is to return whether or not a &lt;code&gt;Time&lt;/code&gt; is within the start and end of a range, but later sections here mention that if a beginning or ending is missing we'd likely want to treat it more like a begin-less range or an endless range.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; - That's a partial hint that ranges can also be used to solve this problem, give it a try and see if you can figure that out as a challenge.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Speaking of unidirectional filtering, the book continues with this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;after_now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;TimeFilter&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kp"&gt;nil&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;span class="n"&gt;in_future&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;in_past&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;array_of_times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;partition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;after_now&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The idea being that &lt;code&gt;partition&lt;/code&gt; can divide a list of times into ones occurring either in the future or in the past. Noted this is one reason so many harp on good variable names, as the ones used here make the intention more immediately clear for this code.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Editing Complaint&lt;/em&gt;: Now the next bit confuses me, and feels poorly edited in context with the rest of the text. It mentions that we could implement this as a method on &lt;code&gt;Enumerable&lt;/code&gt; and goes into a bit about using a class as a &lt;code&gt;Proc&lt;/code&gt;. I feel like a paragraph was cut out here, making it very confusing.&lt;/p&gt;

&lt;p&gt;What I assume this was meaning to say was that one &lt;em&gt;could&lt;/em&gt; patch a method into &lt;code&gt;Enumerable&lt;/code&gt; to achieve a similar effect with time ranges, but a class that can be coerced into a &lt;code&gt;Proc&lt;/code&gt; is more flexible and does not patch Ruby.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h5&gt;
  
  
  The TimeFilter Class
&lt;/h5&gt;

&lt;p&gt;Moving past that, the book then goes on to show an implementation of the class:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;TimeFilter&lt;/span&gt;
  &lt;span class="nb"&gt;attr_reader&lt;/span&gt; &lt;span class="ss"&gt;:start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="ss"&gt;:finish&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;initialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;start&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="vi"&gt;@start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
    &lt;span class="vi"&gt;@finish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_proc&lt;/span&gt;
    &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
      &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;

      &lt;span class="kp"&gt;true&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The purpose of this section was to focus on optimizations that can be made to this implementation.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Note&lt;/em&gt; - Before we get into this, and the book does mention it later, these are micro optimizations. More often than not this is completely overkill for optimizing a program, and the actual issues are going to be much higher level. Prefer code that is first working, readable, and understandable before pursuing these and make sure you have evidence before optimizing at this small of a scale.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The first optimization is around the &lt;code&gt;attr_reader&lt;/code&gt; methods getting called repeatedly in the &lt;code&gt;to_proc&lt;/code&gt; method. To get around that the book mentions binding these to local variables instead to only hit those methods once:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_proc&lt;/span&gt;
  &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
    &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;finish&lt;/span&gt;

    &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
    &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;

    &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The second optimization mentioned is variable hoisting, or moving those local variable bindings up above the &lt;code&gt;Proc&lt;/code&gt; itself:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_proc&lt;/span&gt;
  &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
  &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;finish&lt;/span&gt;

  &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
    &lt;span class="k"&gt;next&lt;/span&gt; &lt;span class="kp"&gt;false&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;

    &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This particular technique works because of closures, as the book mentions, which you can &lt;a href="https://dev.to/baweaver/understanding-ruby-blocks-procs-and-lambdas-24o0"&gt;read about more here&lt;/a&gt;. The short version is that functions in Ruby (&lt;code&gt;Proc&lt;/code&gt;, block, lambda, etc) are closures, they remember the context they're created in, meaning they can access those variables.&lt;/p&gt;

&lt;p&gt;The third optimizations mentioned are around limiting the scope of the function generated in the cases of a start or end date not being present:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;to_proc&lt;/span&gt;
  &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;start&lt;/span&gt;
  &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;self&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;finish&lt;/span&gt;

  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;
    &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="o"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt;
    &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;start&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;elsif&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt;
    &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;lt;=&lt;/span&gt; &lt;span class="n"&gt;finish&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;else&lt;/span&gt;
    &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Just for the sake of curiosity though let's &lt;a href="https://gist.github.com/baweaver/c35262cdd31f583e014b7e47e8848664"&gt;run this through its paces&lt;/a&gt;:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight plaintext"&gt;&lt;code&gt;Warming up --------------------------------------
          Original    66.000  i/100ms
             Local    72.000  i/100ms
     Hoisted Local    88.000  i/100ms
     Filtered Proc    98.000  i/100ms
    Filtered Range    83.000  i/100ms
Calculating -------------------------------------
          Original    655.049  (± 2.6%) i/s - 3.300k in 5.041153s
             Local    709.828  (± 3.9%) i/s - 3.600k in 5.080284s
     Hoisted Local    902.202  (± 2.9%) i/s - 4.576k in 5.076483s
     Filtered Proc    951.916  (± 3.0%) i/s - 4.802k in 5.049386s
    Filtered Range    825.598  (± 2.1%) i/s - 4.150k in 5.028796s
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;You can &lt;a href="https://gist.github.com/baweaver/c35262cdd31f583e014b7e47e8848664"&gt;find the code here&lt;/a&gt;, but note that I've also added a range just to see what'd happen.&lt;/p&gt;

&lt;h5&gt;
  
  
  Constants Example
&lt;/h5&gt;

&lt;p&gt;This section has one more example on replacing constants with locals, but as mentioned in the previous section this is the type of thing you only need if you're really grinding things down to exceptionally small optimizations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;num_arrays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="no"&gt;Array&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;num_arrays&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The first optimization is to hoist the &lt;code&gt;Array&lt;/code&gt; constant:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;num_arrays&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;0&lt;/span&gt;
&lt;span class="n"&gt;array_class&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Array&lt;/span&gt;

&lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;is_a?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;array_class&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
    &lt;span class="n"&gt;num_arrays&lt;/span&gt; &lt;span class="o"&gt;+=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Which doesn't seem very common, but the book puts another more interesting example here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_f&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Optimized&lt;/span&gt;
&lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_f&lt;/span&gt;
&lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;/&lt;/span&gt; &lt;span class="mf"&gt;2.0&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but then reminds us there are some mathematical optimizations:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;max&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;ARGV&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="mi"&gt;0&lt;/span&gt;&lt;span class="p"&gt;].&lt;/span&gt;&lt;span class="nf"&gt;to_f&lt;/span&gt; &lt;span class="o"&gt;*&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;
&lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;value&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;=&lt;/span&gt; &lt;span class="n"&gt;max&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now personally, for me, unless I really really need to optimize things I'm going to avoid bang (&lt;code&gt;!&lt;/code&gt;) methods and mutation in general sections, as very very rarely have I had performance intensive enough sections to justify this level of optimization, but it can be handy to know if you ever find yourself in such a situation.&lt;/p&gt;

&lt;p&gt;Really though, so much of my Ruby knowledge ends up being "just in case" rather than immediately applicable, and quite often I question the necessity of memorizing all of it. That said, if you're maintaining OSS like Jeremy does this type of thing can have multiplicative benefits across a significant number of Ruby applications in the wild.&lt;/p&gt;

&lt;p&gt;Context matters more than strong opinions on how things should be done.&lt;/p&gt;

&lt;h4&gt;
  
  
  Avoiding unsafe optimizations
&lt;/h4&gt;

&lt;p&gt;What I really appreciate here on the book is it mentions some of the cases where you can have issues. It mentions idempotency, or avoiding side-effects with those local variables, and uses this example:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_hash&lt;/span&gt;

&lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and the potential optimization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_hash&lt;/span&gt;
&lt;span class="n"&gt;a_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;

&lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt; &lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;a_value&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and then the trap implementation which will fail:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="nb"&gt;hash&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;some_value&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;to_hash&lt;/span&gt;

&lt;span class="k"&gt;unless&lt;/span&gt; &lt;span class="n"&gt;a_value&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="ss"&gt;:a&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="n"&gt;large_array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;hash&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kp"&gt;true&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;The book mentions this as potentially dangerous as it assumes that the &lt;code&gt;large_array&lt;/code&gt; does not contain an &lt;code&gt;:a&lt;/code&gt; element or a default proc that deals with it. Personally I like the followup example with times a bit better:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;enumerable_of_times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...and the flawed optimization:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;

&lt;span class="n"&gt;enumerable_of_times&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;reject!&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;This one is quite a bit more complicated. &lt;code&gt;Time.now&lt;/code&gt; is going to return a different time when called, introducing variance in the program. Perhaps you want that variance, perhaps not, so one does need to be aware of that. The book mentions cases in which the block yields at an interval slow enough to introduce substantial drift from the first call of &lt;code&gt;Time.now&lt;/code&gt;, but even small drift can introduce all types of difficult bugs to track down.&lt;/p&gt;

&lt;p&gt;The really concrete example which demonstrates the point of this area is if you have a &lt;code&gt;proc&lt;/code&gt; checking whether a time is greater than now:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;greater_than_now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;In this case the definition of &lt;code&gt;now&lt;/code&gt; is very important to be immediately at calling time, rather than having an older reference, meaning optimizing like this will break things:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;Time&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;now&lt;/span&gt;

&lt;span class="n"&gt;greater_than_now&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nb"&gt;proc&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;time&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;time&lt;/span&gt; &lt;span class="o"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;now&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;I really do appreciate that this book takes time to cover these cases instead of just going into optimizations directly.&lt;/p&gt;

&lt;h4&gt;
  
  
  Handling scope gate issues
&lt;/h4&gt;

&lt;p&gt;Now this section can get a bit dense, and covers the visibility scope of local variables:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# nil&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;1&lt;/span&gt;

&lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 'local-variable'&lt;/span&gt;

&lt;span class="k"&gt;module&lt;/span&gt; &lt;span class="nn"&gt;M&lt;/span&gt;
  &lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# nil&lt;/span&gt;

  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;2&lt;/span&gt;

  &lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 'local-variable'&lt;/span&gt;

  &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;C&lt;/span&gt;
    &lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# nil&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;3&lt;/span&gt;

    &lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 'local-variable'&lt;/span&gt;

    &lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;m&lt;/span&gt;
      &lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# nil&lt;/span&gt;

      &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="mi"&gt;4&lt;/span&gt;

      &lt;span class="k"&gt;defined?&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;# 'local-variable'&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;

    &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="c1"&gt;# 3&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="c1"&gt;# 2&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="n"&gt;a&lt;/span&gt; &lt;span class="c1"&gt;# 1&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;That was one of the reasons they'd used a lambda function in the first chapter.&lt;/p&gt;

&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;Editing Note&lt;/em&gt; - The book tends to switch between preferring Proc and Lambda, whereas it might be nicer to have some consistency there. Personally I prefer Lambda, but understand why &lt;code&gt;proc&lt;/code&gt; might be preferred when referencing procs frequently. I still think that's a confusing choice in Ruby to have so many function types.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h4&gt;
  
  
  Naming considerations with local variables
&lt;/h4&gt;

&lt;p&gt;The next section covers conventions in naming variables. The short version of what the book recommends is:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Use &lt;code&gt;lower_case_ascii_snake_case&lt;/code&gt; for local variables, preferably in ASCII&lt;/li&gt;
&lt;li&gt;Just because you &lt;em&gt;can&lt;/em&gt; use emojis does not mean you should&lt;/li&gt;
&lt;li&gt;Non-english languages can justify skipping ASCII, but may make it more difficult to work with&lt;/li&gt;
&lt;li&gt;Careful on how long your names are&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Jeremy is right on length, there's a fine line between &lt;code&gt;is_a_long_phrase_like_this&lt;/code&gt; versus something like &lt;code&gt;long_phrase&lt;/code&gt;. Personally if a variable is that long it may be a hint that the variable is doing too much contextually and needs to be factored out.&lt;/p&gt;

&lt;p&gt;There are three examples used on name length:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="c1"&gt;# Using `a`, which is short for `album`&lt;/span&gt;
&lt;span class="vi"&gt;@albums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Using numbered params&lt;/span&gt;
&lt;span class="vi"&gt;@albums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;_1&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="c1"&gt;# Spelling out the full word&lt;/span&gt;
&lt;span class="vi"&gt;@albums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;As the book mentions &lt;code&gt;a&lt;/code&gt; can be reasonably inferred from context, but that may be vague here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;array&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;a&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Spelling out &lt;code&gt;album&lt;/code&gt; isn't that long, and may be justifiable, but the next example makes a point against spelling things out every time:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;TransactionProcessingSystemReport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;transaction_processing_system_report&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;transaction_processing_system_report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Sure, it's accurate, but that's exhausting to read as the book mentions. It mentions a few abbreviations as alternatives here:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="no"&gt;TransactionProcessingSystemReport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;tps_report&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;tps_report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;

&lt;span class="no"&gt;TransactionProcessingSystemReport&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;report&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Neither of which, to me, lose much value by abbreviating the name in terms of clarity.&lt;/p&gt;

&lt;p&gt;Now the book mentions something interesting: the longer the method or block the more names matter. Using a single-letter name in a long method means the original context is harder to see at a glance, adding a lot more value to longer names.&lt;/p&gt;

&lt;p&gt;There are, however, some common conventions in Ruby and most programming languages at that on single-letter names like:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="mi"&gt;3&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;times&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;type&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="no"&gt;AlbumType&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;i&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;

  &lt;span class="n"&gt;type&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;albums&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="n"&gt;album&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;name&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;

  &lt;span class="nb"&gt;puts&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;&lt;code&gt;i&lt;/code&gt;, &lt;code&gt;j&lt;/code&gt;, &lt;code&gt;k&lt;/code&gt;, and other such single-letters are going to be very familiar to a lot of C and Java programmers used to &lt;code&gt;for&lt;/code&gt; loops. For integers this can make sense, especially as the book mentions for methods like &lt;code&gt;Integer#times&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;It also mentions &lt;code&gt;Hash&lt;/code&gt; cases for key and value being &lt;code&gt;k&lt;/code&gt; and &lt;code&gt;v&lt;/code&gt; respectively:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="nb"&gt;puts&lt;/span&gt; &lt;span class="s2"&gt;"&lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;: &lt;/span&gt;&lt;span class="si"&gt;#{&lt;/span&gt;&lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;length&lt;/span&gt;&lt;span class="si"&gt;}&lt;/span&gt;&lt;span class="s2"&gt;"&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;...but quickly follows with a common case which would be nested hashes and conventions around &lt;code&gt;k2&lt;/code&gt; and such:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;k&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;k2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;v&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;k2&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;v2&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;For this particular case, as the book mentions, &lt;code&gt;options&lt;/code&gt; isn't really a &lt;code&gt;Hash&lt;/code&gt;, it's a collection of keys and values. That means that the typical &lt;code&gt;Hash&lt;/code&gt; convention doesn't really make sense any more no? It suggests this instead:&lt;br&gt;
&lt;/p&gt;

&lt;div class="highlight js-code-highlight"&gt;
&lt;pre class="highlight ruby"&gt;&lt;code&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key_list&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value_list&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
  &lt;span class="n"&gt;key_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
    &lt;span class="n"&gt;value_list&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nf"&gt;each&lt;/span&gt; &lt;span class="k"&gt;do&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt;&lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="o"&gt;|&lt;/span&gt;
      &lt;span class="nb"&gt;p&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;value&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
    &lt;span class="k"&gt;end&lt;/span&gt;
  &lt;span class="k"&gt;end&lt;/span&gt;
&lt;span class="k"&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;/div&gt;



&lt;p&gt;Now this next part confuses me context wise, which involves gateless systems like &lt;code&gt;define_method&lt;/code&gt; out of the blue. It mentions overwriting local variables unintentionally, but I believe this would have been better as its own section with a mention on the nuances of scoping, closures, shadowing, and related materials to give a broader overview. Scope gate does not feel as common a term to me, but I also come from a more functional background, so terms like closure are more familiar to me. Take with a grain of salt.&lt;/p&gt;

&lt;p&gt;With that we're finished up the section on local variables.&lt;/p&gt;

&lt;p&gt;The next section will cover instance variables.&lt;/p&gt;

</description>
      <category>ruby</category>
      <category>books</category>
    </item>
  </channel>
</rss>
