<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom">
  <channel>
    <title>Chris Callahan</title>
    <description>Decoding coding. HTML, CSS, JavaScript. Computer Science. Other thoughts on programming.
</description>
    <link>http://callahan.io/</link>
    <atom:link href="http://callahan.io/feed.xml" rel="self" type="application/rss+xml"/>
    <pubDate>Sat, 02 Jun 2018 19:24:00 +0000</pubDate>
    <lastBuildDate>Sat, 02 Jun 2018 19:24:00 +0000</lastBuildDate>
    <generator>Jekyll v3.7.3</generator>
    
      <item>
        <title>React.Children and the React Top-Level API</title>
        <description>&lt;p&gt;One of the features that drew me in to React was the explicit intention by its authors to create an API with a &lt;a href=&quot;http://2014.jsconf.eu/speakers/sebastian-markbage-minimal-api-surface-area-learning-patterns-instead-of-frameworks.html&quot;&gt;minimal surface area&lt;/a&gt;. This is a great goal, because it allows you to keep the full React API &lt;a href=&quot;http://www.paulgraham.com/head.html&quot;&gt;in your head&lt;/a&gt; when developing your application with React. Writing React code is often focused on creating components and using the &lt;a href=&quot;https://facebook.github.io/react/docs/component-api.html&quot;&gt;component API&lt;/a&gt; and &lt;a href=&quot;https://facebook.github.io/react/docs/component-specs.html&quot;&gt;lifecycle methods&lt;/a&gt;, but there are a few other useful top-level utilities provided in the React API. Below I’ll cover the &lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children&lt;/code&gt; methods for handling the &lt;code class=&quot;highlighter-rouge&quot;&gt;this.props.children&lt;/code&gt; opaque data structure and how I’ve used them in my React apps.&lt;/p&gt;

&lt;h2 id=&quot;reactchildrenmap&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.map&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;The &lt;a href=&quot;https://facebook.github.io/react/blog/2015/03/03/react-v0.13-rc2.html#react.cloneelement&quot;&gt;release notes&lt;/a&gt; for &lt;code class=&quot;highlighter-rouge&quot;&gt;React.cloneElement&lt;/code&gt; discuss a common pattern that consists of using &lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.map&lt;/code&gt; to map over the &lt;code class=&quot;highlighter-rouge&quot;&gt;children&lt;/code&gt; prop passed to a component and returning a cloned version of each child with additional props passed in. This allows you to pass props down from a parent component to a child component without the parent needing to explicitly render that child. This can be a big help in building reusable React components.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'react'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Salmonize&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;cloneElement&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;na&quot;&gt;style&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;backgroundColor&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'salmon'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
          &lt;span class=&quot;na&quot;&gt;color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'seagreen'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;))}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;SalmonBlog&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;posts&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Salmonize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;NavBar&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/Salmonize&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;posts&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;post&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Post&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Salmonize&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
          &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PostHeader&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/Salmonize&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PostBody&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;post&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/Post&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;))}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In this example, the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;NavBar&amp;gt;&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;PostHeader&amp;gt;&lt;/code&gt; elements don’t need to know about their styles, and indeed these components could be used elsewhere without this salmon-inspired color palette. (CSS is also a solution here 😄.) Similarly, the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Salmonize&amp;gt;&lt;/code&gt; component does not need to be aware of the fact that it is rendering the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;Navbar&amp;gt;&lt;/code&gt; or &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;PostHeader&amp;gt;&lt;/code&gt; components, but it is still able to pass its props along to those child components.&lt;/p&gt;

&lt;p&gt;It’s definitely a bit tricky to write truly reusable components in React. If you’re having trouble with this, then this “map and clone” trick can probably help you on the way to achieving this elusive goal.&lt;/p&gt;

&lt;h2 id=&quot;reactchildrenforeach&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.forEach&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;Similar to &lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.map&lt;/code&gt;, but has no return value. I haven’t used this method as I haven’t had the need to loop over a component’s children and do something other than augment props or render UI. There is a pretty elegant use case for this in Pete Hunt’s &lt;code class=&quot;highlighter-rouge&quot;&gt;rwb&lt;/code&gt; repo &lt;a href=&quot;https://github.com/petehunt/rwb/blob/f84b5ad2c8d2099b857a96ddfbd6db1cfef4ad70/lib/getAsyncBundles.js&quot;&gt;here&lt;/a&gt;.&lt;/p&gt;

&lt;h2 id=&quot;reactchildrencount&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.count&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;This method returns the number of child components in the &lt;code class=&quot;highlighter-rouge&quot;&gt;children&lt;/code&gt; argument passed to it. Again, I haven’t come across the use case for this one personally. Most of the use cases I came across in a cursory Github search were simply confirming whether or not any children had been passed to a component, as in the above example from Pete Hunt.&lt;/p&gt;

&lt;h2 id=&quot;reactchildrenonly&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.only&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;This can come in handy when you want to ensure that a component only has one child, and throw an error if this condition is not met. There’s a good example of this in a previous version of Cheng Lou’s &lt;code class=&quot;highlighter-rouge&quot;&gt;react-radio-group&lt;/code&gt; component &lt;a href=&quot;https://github.com/chenglou/react-radio-group/blob/9a992f3bbc1bffeb1dc993e42b0f4842ab299f42/index.jsx#L42&quot;&gt;here&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;export&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;default&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;// ...&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;selectedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;props&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;renderedChildren&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;radio&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;selectedValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;onChange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;));&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;renderedChildren&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;only&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;renderedChildren&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;a href=&quot;https://github.com/chenglou/react-radio-group/blob/9a992f3bbc1bffeb1dc993e42b0f4842ab299f42/example/example.jsx#L22&quot;&gt;The example app in the repo&lt;/a&gt; complies with this contract.&lt;/p&gt;

&lt;h2 id=&quot;reactchildrentoarray&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.toArray&lt;/code&gt;&lt;/h2&gt;

&lt;p&gt;This method converts the &lt;code class=&quot;highlighter-rouge&quot;&gt;children&lt;/code&gt; prop of a component into a plain JavaScript array, which can give you a bit more flexibility than &lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.map&lt;/code&gt; provides. &lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.toArray&lt;/code&gt; came in handy for me recently when I wanted to render a list of items with a divider element interspersed between them. This led me to create an &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;IntersperseDividers&amp;gt;&lt;/code&gt; component to accomplish just that.&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;import&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;from&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'react'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;IntersperseDividers&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;toArray&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;children&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;child&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;nx&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hr&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;${&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;--divider`&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;se&quot;&gt;)&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;;
&lt;/span&gt;      &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;elements&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[])}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;const&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;List&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;({&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;})&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;IntersperseDividers&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;data&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;((&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;key&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;))}&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/IntersperseDividers&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I got caught on this component for a moment because of an error thrown when I tried to directly return an array of elements. I fixed it by wrapping the array returned by &lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.toArray()&lt;/code&gt; in a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;div&amp;gt;&lt;/code&gt;, just like in the &lt;code class=&quot;highlighter-rouge&quot;&gt;React.Children.map&lt;/code&gt; example above. You wouldn’t need this wrapping &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;div&amp;gt;&lt;/code&gt; if the content was inlined in the &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;List&amp;gt;&lt;/code&gt; component, so it’s a tradeoff for better component reusability at the expense of increased divitis.&lt;/p&gt;

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

&lt;p&gt;If you haven’t read through it before, I’d recommend taking a minute to skim through the &lt;a href=&quot;https://facebook.github.io/react/docs/top-level-api.html&quot;&gt;top-level API section&lt;/a&gt; of the React docs. Though the API surface area is small, there are some hidden gems within.&lt;/p&gt;
</description>
        <pubDate>Fri, 16 Sep 2016 18:06:19 +0000</pubDate>
        <link>http://callahan.io/blog/2016/09/16/react-dot-children-and-the-react-top-level-api</link>
        <guid isPermaLink="true">http://callahan.io/blog/2016/09/16/react-dot-children-and-the-react-top-level-api</guid>
        
        
      </item>
    
      <item>
        <title>Debugging CouchDB Design Documents</title>
        <description>&lt;p&gt;When making changes to a CouchDB design document (or ddoc), I often use &lt;code class=&quot;highlighter-rouge&quot;&gt;curl&lt;/code&gt; to make queries and see if the data returned is what I expected. Sometimes, however, this does not provide enough information to help me get to the bottom of why the ddoc does not behave as anticipated. Here is my process for debugging JavaScript code in CouchDB design documents. (Note: This blog post assumes CouchDB is &lt;a href=&quot;https://pouchdb.com/guides/setup-couchdb.html#installing-couchdb&quot;&gt;installed&lt;/a&gt; and running on  your machine.)&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR: I show you how to use &lt;code class=&quot;highlighter-rouge&quot;&gt;console.log&lt;/code&gt; debugging inside of CouchDB design documents.&lt;/strong&gt;&lt;/p&gt;

&lt;h2 id=&quot;how-to-configure-couchdb&quot;&gt;How to Configure CouchDB&lt;/h2&gt;

&lt;p&gt;The first step is to locate CouchDB’s configuration settings on your machine. Type &lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb -c&lt;/code&gt; into the command line:&lt;/p&gt;
&lt;pre&gt;
$ couchdb -c
/usr/local/etc/couchdb/default.ini
/usr/local/etc/couchdb/local.ini
/usr/local/etc/couchdb/local.d/couchdb-lucene.ini
&lt;/pre&gt;

&lt;p&gt;This output is a list files containint of CouchDB’s default configurations and any custom overrides you define. Open the &lt;code class=&quot;highlighter-rouge&quot;&gt;local.ini&lt;/code&gt; file in your preferred text editor and navigate down to the &lt;code class=&quot;highlighter-rouge&quot;&gt;[log]&lt;/code&gt; section. You may see the following text:&lt;/p&gt;

&lt;pre&gt;
[log]
;level = debug
&lt;/pre&gt;

&lt;p&gt;The leading semicolon indicates this line is commented out. I am not totally sure why CouchDB uses &lt;code class=&quot;highlighter-rouge&quot;&gt;.ini&lt;/code&gt; files for its config files, as the database is primarily written in Erlang and contains a JavaScript runtime (SpiderMonkey).&lt;/p&gt;

&lt;p&gt;Uncomment this line (delete the semicolon), restart CouchDB, and you will see quite a bit of output in the console, starting with something like this:&lt;/p&gt;

&lt;pre&gt;
$ couchdb
Apache CouchDB 1.6.1 (LogLevel=debug) is starting.
Configuration Settings [&quot;/usr/local/etc/couchdb/default.ini&quot;,
                        &quot;/usr/local/etc/couchdb/local.ini&quot;,
                        &quot;/usr/local/etc/couchdb/local.d/couchdb-lucene.ini&quot;]:
# About 100 more lines of lots of nice config info follows
&lt;/pre&gt;

&lt;p&gt;This being CouchDB, we can of course set the log level using Couch’s HTTP API:&lt;/p&gt;

&lt;pre&gt;
$ curl -X PUT 127.0.0.1:5984/_config/log/level -d '&quot;info&quot;'
&quot;info&quot;
&lt;/pre&gt;

&lt;p&gt;(Note that you will have to pass in admin credentials here if the CouchDB you’re running is not in &lt;a href=&quot;http://guide.couchdb.org/draft/security.html#party&quot;&gt;admin party&lt;/a&gt; mode.)&lt;/p&gt;

&lt;p&gt;The best part about this is that you don’t have to restart the database, logging will begin immediately. Thanks, Erlang!&lt;/p&gt;

&lt;p&gt;The CouchDB configuration settings can also be changed in the admin UI of Futon. Visit &lt;code class=&quot;highlighter-rouge&quot;&gt;http://localhost:5984/_utils&lt;/code&gt;, log in if necessary, then click on “Configuration” on the righthand panel. If this looks familiar, it is because it is a web interface for the local config files listed when you ran &lt;code class=&quot;highlighter-rouge&quot;&gt;couchdb -c&lt;/code&gt; above. You can edit the log level here as well – navigate down to the “log” section, double click on the text next to “level” (should be “info”), type in “debug”, and click the green check mark. You’ll notice the following output gets logged by CouchDB:&lt;/p&gt;

&lt;pre&gt;
=SUPERVISOR REPORT==== 4-Jun-2016::15:23:18 ===
     Supervisor: {local,couch_primary_services}
     Context:    child_terminated
     Reason:     normal
     Offender:   [{pid,&amp;lt;0.258.0&amp;gt;},
                  {id,couch_log},
                  {mfargs,{couch_log,start_link,[]}},
                  {restart_type,permanent},
                  {shutdown,brutal_kill},
                  {child_type,worker}]

[info] [&amp;lt;0.157.0&amp;gt;] 127.0.0.1 - - PUT /_config/log/level 200
&lt;/pre&gt;

&lt;p&gt;The last line shows that under the hood the Futon UI is simply making the same &lt;code class=&quot;highlighter-rouge&quot;&gt;PUT&lt;/code&gt; request over HTTP you made above using &lt;code class=&quot;highlighter-rouge&quot;&gt;curl&lt;/code&gt; to change the log level. Above that there is a “Supervisor Report” from the CouchDB internals stating that the &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_log&lt;/code&gt; worker process was… abruptly?… restarted by the &lt;code class=&quot;highlighter-rouge&quot;&gt;couch_primary_services&lt;/code&gt; supervisor process.&lt;/p&gt;

&lt;p&gt;The CouchDB docs has a good roundup of &lt;a href=&quot;http://docs.couchdb.org/en/1.6.1/config/logging.html&quot;&gt;all of the different log levels&lt;/a&gt; Couch supports. I typically stick with “info” in development to have a window into all of the incoming requests to CouchDB being logged in real time, but I’ll sometimes switch to “debug” mode to view in more detail all of the headers / cookies that are part of the incoming HTTP requests. (Note that neither of these settings are recommended for logging in production.)&lt;/p&gt;

&lt;p&gt;Now that you’ve set up CouchDB to be a bit more verbose, run:&lt;/p&gt;

&lt;pre&gt;
curl 127.0.0.1:5984
&lt;/pre&gt;

&lt;p&gt;Back in CouchDB, you’ll see the following output:&lt;/p&gt;

&lt;pre&gt;
[debug] [&amp;lt;0.225.0&amp;gt;] 'GET' / {1,1} from &quot;127.0.0.1&quot;
Headers: [{'Accept',&quot;*/*&quot;},
          {'Host',&quot;127.0.0.1:5984&quot;},
          {'User-Agent',&quot;curl/7.43.0&quot;}]
[debug] [&amp;lt;0.225.0&amp;gt;] OAuth Params: []
[info] [&amp;lt;0.225.0&amp;gt;] 127.0.0.1 - - GET / 200
&lt;/pre&gt;

&lt;p&gt;Simpy perusing the logs of incoming requests and outgoing responses can be very informative and helpful if something is going wrong. But you can also take the debugging one step further with &lt;code class=&quot;highlighter-rouge&quot;&gt;log&lt;/code&gt;.&lt;/p&gt;

&lt;h2 id=&quot;consolelog-debugging-inside-couchdb&quot;&gt;“&lt;code class=&quot;highlighter-rouge&quot;&gt;console.log&lt;/code&gt; Debugging” Inside CouchDB&lt;/h2&gt;

&lt;p&gt;CouchDB exposes a global &lt;code class=&quot;highlighter-rouge&quot;&gt;log&lt;/code&gt; function inside of design documents that allows you to write custom messages to CouchDB’s logs. This is similar to using &lt;code class=&quot;highlighter-rouge&quot;&gt;console.log()&lt;/code&gt; in the dev tools console in the browser or in node.&lt;/p&gt;

&lt;p&gt;To see how this works in action, first create a new database and insert a design document:&lt;/p&gt;

&lt;pre&gt;
$ curl -X PUT 127.0.0.1:5984/test
{
  &quot;ok&quot;: true
}
$ curl -X PUT 127.0.0.1:5984/test/_design/test \
&amp;gt; -d '{ &quot;_id&quot;: &quot;_design/test&quot;, &quot;views&quot;: { &quot;greetingDocs&quot;: { &quot;map&quot;: &quot;function(doc) { if (doc.hello) { log(\&quot;This doc says hello, \&quot; + doc.hello); emit(doc._id, null); } }&quot;, &quot;reduce&quot;: &quot;_count&quot; } } }'
{
  &quot;ok&quot;: true,
  &quot;id&quot;: &quot;_design/test&quot;,
  &quot;rev&quot;: &quot;1-ea73ae4cba8ca3ca7618c23185ef92d2&quot;
}
&lt;/pre&gt;

&lt;p&gt;Here’s roughly how that ddoc looks in JavaScript (sans stringified functions):&lt;/p&gt;

&lt;div class=&quot;language-js highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nl&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;_design/test&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;views&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nl&quot;&gt;greetingDocs&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;nl&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
        &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;This doc says hello, &quot;&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;hello&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
          &lt;span class=&quot;nx&quot;&gt;emit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;doc&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_id&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
      &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
      &lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;_count&quot;&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that you’ve got a barebones design doc, you can see the logging at work by adding a new document to the &lt;code class=&quot;highlighter-rouge&quot;&gt;test&lt;/code&gt; database:&lt;/p&gt;

&lt;pre&gt;
$ curl -X PUT 127.0.0.1:5984/test/one \
&amp;gt; -d '{ &quot;_id&quot;: &quot;one&quot;, &quot;hello&quot;: &quot;I am log&quot; }'
{
  &quot;ok&quot;: true,
  &quot;id&quot;: &quot;one&quot;,
  &quot;rev&quot;: &quot;1-6feff67ca27f6cc570f9ae43385730f8&quot;
}
$ curl 127.0.0.1:5984/test/_design/test/_view/greetingDocs
{
  &quot;rows&quot;: [
    { &quot;key&quot;: null, &quot;value&quot; : 1 }
  ]
}
&lt;/pre&gt;

&lt;p&gt;In the couch logs you will see something like this:&lt;/p&gt;

&lt;pre&gt;
[debug] [&amp;lt;0.99.0&amp;gt;] 'GET' /test/_design/test/_view/greetingDocs {1,1} from &quot;127.0.0.1&quot;
Headers: [{'Accept',&quot;*/*&quot;},
          {'Host',&quot;127.0.0.1:5984&quot;},
          {'User-Agent',&quot;curl/7.43.0&quot;}]
[debug] [&amp;lt;0.99.0&amp;gt;] OAuth Params: []
[info] [&amp;lt;0.991.0&amp;gt;] Opening index for db: test idx: _design/test sig: &quot;eff5145ec110e4f61dbe8a2b446588e8&quot;
[info] [&amp;lt;0.996.0&amp;gt;] Starting index update for db: test idx: _design/test
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Input  :: [&quot;reset&quot;,{&quot;reduce_limit&quot;:false,&quot;timeout&quot;:5000}]
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: true
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Input  :: [&quot;add_fun&quot;,&quot;function(doc) { if (doc.hello) { log(\&quot;This doc says hello, \&quot; + doc.hello); emit(doc._id, null); } }&quot;]
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: true
[debug] [&amp;lt;0.84.0&amp;gt;] New task status for &amp;lt;0.1001.0&amp;gt;: [{changes_done,3},
                                                    {database,&amp;lt;&amp;lt;&quot;test&quot;&amp;gt;&amp;gt;},
                                                    {design_document,
                                                     &amp;lt;&amp;lt;&quot;_design/test&quot;&amp;gt;&amp;gt;},
                                                    {progress,150},
                                                    {started_on,1465068874},
                                                    {total_changes,2},
                                                    {type,indexer},
                                                    {updated_on,1465068874}]
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Input  :: [&quot;map_doc&quot;,{&quot;_id&quot;:&quot;one&quot;,&quot;_rev&quot;:&quot;1-6feff67ca27f6cc570f9ae43385730f8&quot;,&quot;hello&quot;:&quot;I am log&quot;}]
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: [&quot;log&quot;,&quot;This doc says hello, I am log&quot;]
[info] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Log :: This doc says hello, I am log
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: [[[&quot;one&quot;,null]]]
[debug] [&amp;lt;0.991.0&amp;gt;] Updated index for db: test idx: _design/test seq: 2
[info] [&amp;lt;0.996.0&amp;gt;] Index update finished for db: test idx: _design/test
[debug] [&amp;lt;0.991.0&amp;gt;] Updated index for db: test idx: _design/test seq: 2
[info] [&amp;lt;0.99.0&amp;gt;] 127.0.0.1 - - GET /test/_design/test/_view/greetingDocs 200
&lt;/pre&gt;

&lt;p&gt;It looks a bit cryptic, but towards the bottom you might notice four lines in particular:&lt;/p&gt;

&lt;pre&gt;
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Input  :: [&quot;map_doc&quot;,{&quot;_id&quot;:&quot;one&quot;,&quot;_rev&quot;:&quot;1-6feff67ca27f6cc570f9ae43385730f8&quot;,&quot;hello&quot;:&quot;I am log&quot;}]
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: [&quot;log&quot;,&quot;This doc says hello, I am log&quot;]
[info] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Log :: This doc says hello, I am log
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: [[[&quot;one&quot;,null]]]
&lt;/pre&gt;

&lt;p&gt;On the third line (with &lt;code class=&quot;highlighter-rouge&quot;&gt;Log ::&lt;/code&gt;) we can see our message from &lt;code class=&quot;highlighter-rouge&quot;&gt;log&lt;/code&gt;! It’s also interesting to see the &lt;code class=&quot;highlighter-rouge&quot;&gt;Input&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Output&lt;/code&gt; CouchDB is writing here. First, in the &lt;code class=&quot;highlighter-rouge&quot;&gt;Input&lt;/code&gt; line, the doc with &lt;code class=&quot;highlighter-rouge&quot;&gt;_id&lt;/code&gt; of &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;one&quot;&lt;/code&gt; that you just &lt;code class=&quot;highlighter-rouge&quot;&gt;PUT&lt;/code&gt; to the database is being run through something called &lt;code class=&quot;highlighter-rouge&quot;&gt;map_doc&lt;/code&gt;. This produces two &lt;code class=&quot;highlighter-rouge&quot;&gt;Output&lt;/code&gt;s: first the log, and then the doc’s &lt;code class=&quot;highlighter-rouge&quot;&gt;_id&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;null&lt;/code&gt;, which were emitted using &lt;code class=&quot;highlighter-rouge&quot;&gt;emit(doc._id, null)&lt;/code&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; function of the &lt;code class=&quot;highlighter-rouge&quot;&gt;greetingDocs&lt;/code&gt; view.&lt;/p&gt;

&lt;p&gt;Running the same query on the view again will &lt;em&gt;not&lt;/em&gt; write the same message to the log. My speculation is that CouchDB caches the results of the &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce&lt;/code&gt; functions in its views, so the &lt;code class=&quot;highlighter-rouge&quot;&gt;map&lt;/code&gt; function won’t be run again (and therefore our message won’t be logged again) until either the ddoc changes or a new document is added to / updated in the database.&lt;/p&gt;

&lt;p&gt;Let’s update the doc to test this assumption:&lt;/p&gt;

&lt;pre&gt;
$ curl -X PUT 127.0.0.1:5984/test/one \
&amp;gt; -d '{ &quot;_id&quot;: &quot;one&quot;, &quot;_rev&quot;: &quot;1-6feff67ca27f6cc570f9ae43385730f8&quot;, &quot;hello&quot;: &quot;this is log()&quot; }'
{
  &quot;ok&quot;: true,
  &quot;id&quot;: &quot;one&quot;,
  &quot;rev&quot;: &quot;2-83ba9fe4df631f7e1af0b079baf1948b&quot;
}
&lt;/pre&gt;

&lt;p&gt;Indeed, when we query the view again, the CouchDB logs contain what we’re looking for:&lt;/p&gt;

&lt;pre&gt;
$ curl 127.0.0.1:5984/test/_design/test/_view/greetingDocs
{
  &quot;rows&quot;: [
    { &quot;key&quot;: null, &quot;value&quot; : 1 }
  ]
}
&lt;/pre&gt;

&lt;pre&gt;
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Input  :: [&quot;map_doc&quot;,{&quot;_id&quot;:&quot;one&quot;,&quot;_rev&quot;:&quot;2-83ba9fe4df631f7e1af0b079baf1948b&quot;,&quot;hello&quot;:&quot;this is log()&quot;}]
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: [&quot;log&quot;,&quot;This doc says hello, this is log()&quot;]
[info] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Log :: This doc says hello, this is log()
[debug] [&amp;lt;0.715.0&amp;gt;] OS Process #Port&amp;lt;0.3200&amp;gt; Output :: [[[&quot;one&quot;,null]]]
&lt;/pre&gt;

&lt;h2 id=&quot;wrapping-up&quot;&gt;Wrapping up&lt;/h2&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;log&lt;/code&gt; is a convenient way to quickly do &lt;code class=&quot;highlighter-rouge&quot;&gt;console.log&lt;/code&gt; debugging inside of your CouchDB design documents. While a full-fledged debugger REPL like the one shown in &lt;a href=&quot;https://jhs.iriscouch.com/files/debugger/debug.html&quot;&gt;this video&lt;/a&gt; seems quite amazing, you can still get quite far with good old &lt;code class=&quot;highlighter-rouge&quot;&gt;log&lt;/code&gt;!&lt;/p&gt;
</description>
        <pubDate>Sat, 04 Jun 2016 19:40:09 +0000</pubDate>
        <link>http://callahan.io/blog/2016/06/04/debugging-couchdb-design-documents</link>
        <guid isPermaLink="true">http://callahan.io/blog/2016/06/04/debugging-couchdb-design-documents</guid>
        
        
      </item>
    
      <item>
        <title>Resources for Learning React &amp;amp; Flux</title>
        <description>&lt;p&gt;I’ve recently had a few people ask me about resources for learning React.js and Flux, so I figured I’d put all of the resources I’ve used in one spot. Please leave a comment if you find any of these useful/useless or have any good resources I’ve left out!&lt;/p&gt;

&lt;h3 id=&quot;why-react&quot;&gt;Why React?&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;The unexamined 3rd party library is not worth using&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/react/docs/why-react.html&quot;&gt;Abridged Version&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://jlongster.com/Removing-User-Interface-Complexity,-or-Why-React-is-Awesome&quot;&gt;Unabridged Version&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;react-basics&quot;&gt;React Basics&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;React 101&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.jackcallister.com/2015/01/05/the-react-quick-start-guide.html&quot;&gt;Basics on components, props, and state&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/react/docs/thinking-in-react.html&quot;&gt;Turning mockups into React components&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/react/docs/multiple-components.html&quot;&gt;Composing multiple components&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;flux&quot;&gt;Flux&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Facebook’s architecture pattern for organizing large React apps&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Shameless plug: &lt;a href=&quot;http://callahan.io/blog/2014/11/23/88-mph-with-flux-and-react/&quot;&gt;My Intro to Flux blog post&lt;/a&gt;
  – some helpful links on the bottom too&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.andrewray.me/flux-for-stupid-people/&quot;&gt;Flux for Stupid People&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/flux/docs/overview.html#content&quot;&gt;Facebook’s Flux Overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/flux/tree/master/examples/flux-chat/&quot;&gt;Facebook’s Flux chat sample app&lt;/a&gt; – great code to dive into for a standard implementation of Facebook-flavored Flux&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;react-router&quot;&gt;React Router&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Inspired by Ember Router, a great addition to React apps&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/rackt/react-router/blob/master/docs/guides/overview.md&quot;&gt;React Router overview&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/rackt/react-router&quot;&gt;Github repo&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;server-side-rendering&quot;&gt;Server-Side Rendering&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Learn the way of &lt;code class=&quot;highlighter-rouge&quot;&gt;React.renderToString()&lt;/code&gt;&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mhart/react-server-example&quot;&gt;Simple React server example&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/zertosh/ssr-demo-kit&quot;&gt;React server-side rendering demo kit&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;tutorials&quot;&gt;Tutorials&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Learn by doing&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/mking/react-hn&quot;&gt;Make Hacker News with React&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;Scotch.io React &amp;amp; Flux tutorials:
    &lt;ol&gt;
      &lt;li&gt;&lt;a href=&quot;https://scotch.io/tutorials/learning-react-getting-started-and-concepts&quot;&gt;Learning React: Getting started and concepts&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://scotch.io/tutorials/build-a-real-time-twitter-stream-with-node-and-react-js&quot;&gt;Build a real time Twitter stream with Node and React.js&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://scotch.io/tutorials/getting-to-know-flux-the-react-js-architecture&quot;&gt;Getting to know Flux, the React.js architecture&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;https://scotch.io/tutorials/creating-a-simple-shopping-cart-with-react-js-and-flux&quot;&gt;Creating a simple shopping cart with React.js and Flux&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://twitter.com/biesnecker&quot;&gt;John Biesnecker&lt;/a&gt;’s React Tutorials:
    &lt;ol&gt;
      &lt;li&gt;&lt;a href=&quot;http://biesnecker.com/2014/10/21/building-a-card-game-war-in-react/&quot;&gt;Building a card game (war) with React&lt;/a&gt;&lt;/li&gt;
      &lt;li&gt;&lt;a href=&quot;http://biesnecker.com/2014/10/22/using-reactjs-to-draw-dynamic-svgs/&quot;&gt;Using React.js to draw dynamic SVGs&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;cool-react-projects&quot;&gt;Cool React Projects&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;React rocks&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://react.rocks/&quot;&gt;react.rocks&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;official-documentation&quot;&gt;Official Documentation&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Still the best and most comprehensive resource out there&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/react/docs/getting-started.html&quot;&gt;React docs&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/flux/docs/overview.html&quot;&gt;Flux docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;h3 id=&quot;read-the-source-code&quot;&gt;Read the Source Code&lt;/h3&gt;
&lt;p&gt;&lt;em&gt;Your great changes to React &amp;amp; Flux are just a pull request away…&lt;/em&gt;&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/react&quot;&gt;React source code&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/flux&quot;&gt;Flux source code&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Fri, 16 Jan 2015 16:34:16 +0000</pubDate>
        <link>http://callahan.io/blog/2015/01/16/resources-for-learning-react-and-flux</link>
        <guid isPermaLink="true">http://callahan.io/blog/2015/01/16/resources-for-learning-react-and-flux</guid>
        
        
      </item>
    
      <item>
        <title>Array Iteration Methods in JavaScript</title>
        <description>&lt;p&gt;When I first started learning JavaScript, I went through a number of tutorials that showed how to iterate over collections in an imperative style using a &lt;code class=&quot;highlighter-rouge&quot;&gt;for&lt;/code&gt; loop:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Pushing Hands'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'The Wedding Banquet'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Eat Drink Man Woman'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;for&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;length&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;' was directed by Ang Lee.'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// &quot;Pushing Hands was directed by Ang Lee.&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// &quot;The Wedding Banquet was directed by Ang Lee.&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// &quot;Eat Drink Man Woman was directed by Ang Lee.&quot;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Before ES5, this was the best available way to iterate over an array, but now there are a number of more expressive, idiomatic, and functional ways of iterating over JavaScript arrays.&lt;/p&gt;

&lt;h3 id=&quot;the-big-three-map-filter--reduce&quot;&gt;The Big Three: &lt;code class=&quot;highlighter-rouge&quot;&gt;map()&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;filter()&lt;/code&gt; &amp;amp; &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt;&lt;/h3&gt;

&lt;h4 id=&quot;arrayprototypemap&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype.map()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;map()&lt;/code&gt; is the array method I find myself using all the time when writing JavaScript code. The conceit is simple: &lt;code class=&quot;highlighter-rouge&quot;&gt;map()&lt;/code&gt; takes a callback function as a parameter, calls this function on each item in the array, and returns a new array of the same length as the initial array that contains the resulting values.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Life of Pi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2012&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Taking Woodstock'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2009&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Lust, Caution'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2007&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Brokeback Mountain'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2005&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Hulk'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2003&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;releaseYears&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;releaseYears&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;releaseYears&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [2012, 2009, 2007, 2005, 2003]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This can be simplified even further by extracting the function and passing it as an argument to &lt;code class=&quot;highlighter-rouge&quot;&gt;map()&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;releaseYears&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;extractYear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;releaseYears&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;extractYear&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;releaseYears&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [2012, 2009, 2007, 2005, 2003]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here &lt;code class=&quot;highlighter-rouge&quot;&gt;movie&lt;/code&gt; is being implicitly passed as an argument to the &lt;code class=&quot;highlighter-rouge&quot;&gt;extractYear()&lt;/code&gt; function, but the behavior is the same as above.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/map&quot;&gt;MDN Documentation - Array.prototype.map()&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;arrayprototypefilter&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype.filter()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;filter()&lt;/code&gt; is intuitively named: it calls a callback function on each item in an array, filters out items that return a falsy value, and returns a new array with the remaining items (those that the callback returns a truthy value for).&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;truthyAndFalsy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;-&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;undefined&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;null&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;4&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;5&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;NaN&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;6&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;7&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;truthy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;truthy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;truthyAndFalsy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;truthy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [1, 2, 3, 4, 5, 6, 7]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Using the opposite test case, we can see the seven falsy values in JavaScript:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;truthyAndFalsy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;...&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;falsy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;falsy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;truthyAndFalsy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;item&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;falsy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// [-0, 0, undefined, null, &quot;&quot;, NaN, false]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While 0 being falsy is a “classic JavaScript gotcha”, the point remains that &lt;code class=&quot;highlighter-rouge&quot;&gt;filter()&lt;/code&gt; is a powerful tool for collecting a subset of your data that matches certain criteria.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/filter&quot;&gt;MDN Documentation - Array.prototype.filter()&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;arrayprototypereduce&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype.reduce()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt; has been the hardest of all FP methods for me to fully embrace, but it can be extremely useful in certain cases. The core idea of &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt; is that it iterates over an array and returns exactly one value. The return value is commonly a sum or count of some property of the items in the array, but &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt; is quite flexible in what it can produce.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Brokeback Mountain'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'won'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Crouching Tiger, Hidden Dragon'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nominated'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Hulk'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Life of Pi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'won'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'The Ice Storm'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;bestDirectorWins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;bestDirectorWins&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bestDirectorOscar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'won'&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bestDirectorWins&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// 2&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here the &lt;code class=&quot;highlighter-rouge&quot;&gt;previousValue&lt;/code&gt; argument is the accumulator that we increment if Ang Lee won an Oscar for best director for the movie we’re iterating over, and the &lt;code class=&quot;highlighter-rouge&quot;&gt;currentValue&lt;/code&gt; argument is item being iterated over. As there is no &lt;code class=&quot;highlighter-rouge&quot;&gt;previousValue&lt;/code&gt; when iterating over the first item, we can initialize it to 0 as an optional second parameter to the &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt; function.&lt;/p&gt;

&lt;p&gt;Though it can seem somewhat esoteric at first, &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt; has grown on me significantly in the past few months – partly because of using MapReduce views in CouchDB views, and partly because of learning more about the benefits of functional programming.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduce&quot;&gt;MDN Documentation - Array.prototype.reduce()&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;friends-of-reduce&quot;&gt;Friends of &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt;&lt;/h3&gt;

&lt;h4 id=&quot;arrayprototypereduceright&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype.reduceRight()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;Having grasped &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt;, it is not a far stretch to get &lt;code class=&quot;highlighter-rouge&quot;&gt;reduceRight()&lt;/code&gt;. Whereas &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt; iterates over an array from left to right, &lt;code class=&quot;highlighter-rouge&quot;&gt;reduceRight()&lt;/code&gt; iterates from right to left. This does not make a difference for the standard sum/count use cases, but it can come in handy for other purposes. For example, if we have an array of Ang Lee movies sorted in reverse chronological order, we could use &lt;code class=&quot;highlighter-rouge&quot;&gt;reduceRight()&lt;/code&gt; to sort these movies in chronological order by decade.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Life of Pi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2012&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Brokeback Mountain'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2005&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Crouching Tiger, Hidden Dragon'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'The Wedding Banquet'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;year&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1993&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;],&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;moviesByDecade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addMovieToDecade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;filmography&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;decade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;filmography&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;decade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;filmography&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;decade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;push&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;filmography&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;decade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;filmography&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;moviesByDecade&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduceRight&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2010&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addMovieToDecade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;2010s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;year&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2000&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addMovieToDecade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;2000s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;addMovieToDecade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;1990s&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;moviesByDecade&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// {&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//   &quot;1990s&quot;: [&quot;The Wedding Banquet&quot;],&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//   &quot;2000s&quot;: [&quot;Crouching Tiger, Hidden Dragon&quot;, &quot;Brokeback Mountain&quot;],&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;//   &quot;2010s&quot;: [&quot;Life of Pi&quot;]&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// }&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/reduceRight&quot;&gt;MDN Documentation - Array.prototype.reduceRight()&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;arrayprototypeevery&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype.every()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt; checks to see if all items in an array return a truthy value for the callback function. If they all do, &lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt; returns &lt;code class=&quot;highlighter-rouge&quot;&gt;true&lt;/code&gt;; otherwise, it returns &lt;code class=&quot;highlighter-rouge&quot;&gt;false&lt;/code&gt;. Given what we know about &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt;, it seems like &lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt; is achieving a similar purpose: boiling an array down to a single value. It is therefore pretty straightforward to implement our own version of &lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt; based on &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt;. (Note, this is a simplified version, as &lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt; can take an optional &lt;code class=&quot;highlighter-rouge&quot;&gt;thisArg&lt;/code&gt; argument).&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;myEvery&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;true&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// every() returns true for empty arrays&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;myEvery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// true&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;myEvery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// false&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;myEvery&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unlike my crude implementation, &lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt; is optimized to return immediately if a falsy value is returned from the callback. Personally, I haven’t used &lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt; much – I prefer to use &lt;code class=&quot;highlighter-rouge&quot;&gt;map()&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;filter()&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/every&quot;&gt;MDN Documentation - Array.prototype.every()&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h4 id=&quot;arrayprototypesome&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype.some()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;Similar to &lt;code class=&quot;highlighter-rouge&quot;&gt;every()&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;some()&lt;/code&gt; iterates over an array and returns &lt;code class=&quot;highlighter-rouge&quot;&gt;true&lt;/code&gt; if any items in the array return a truthy value, and &lt;code class=&quot;highlighter-rouge&quot;&gt;false&lt;/code&gt; if none do. This can also be (again, crudely) expressed in terms of &lt;code class=&quot;highlighter-rouge&quot;&gt;reduce()&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;Array&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mySome&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;reduce&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;previousValue&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;currentValue&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// some() returns false for empty arrays&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;

&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mySome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;10&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// true&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mySome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// true&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mySome&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;num&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;  &lt;span class=&quot;c1&quot;&gt;// false&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/some&quot;&gt;MDN Documentation - Array.prototype.some()&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;a-more-expressive-for-idiom&quot;&gt;A More Expressive &lt;code class=&quot;highlighter-rouge&quot;&gt;for&lt;/code&gt; Idiom?&lt;/h3&gt;

&lt;h4 id=&quot;arrayprototypeforeach&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype.forEach()&lt;/code&gt;&lt;/h4&gt;

&lt;p&gt;To me, &lt;code class=&quot;highlighter-rouge&quot;&gt;forEach()&lt;/code&gt; appears to be a direct successor to the &lt;code class=&quot;highlighter-rouge&quot;&gt;for (i = 0; i &amp;lt; x.length; i += 1) {}&lt;/code&gt; example above. It is a basic iterator that gives you access to one item in an array at a time, and returns &lt;code class=&quot;highlighter-rouge&quot;&gt;undefined&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Brokeback Mountain'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'won'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Crouching Tiger, Hidden Dragon'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nominated'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Hulk'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'Life of Pi'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'won'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'The Ice Storm'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;bestDirectorOscar&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kc&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;];&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;angLeeMovies&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;forEach&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bestDirectorOscar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'won'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Ang Lee won an Oscar for best director for '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;bestDirectorOscar&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;===&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'nominated'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;console&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;log&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'Ang Lee was nominated for an Oscar for best director for '&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;movie&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;title&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;// &quot;Ang Lee won an Oscar for best director for Brokeback Mountain&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// &quot;Ang Lee was nominated for an Oscar for best director for Crouching Tiger, Hidden Dragon&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// &quot;Ang Lee won an Oscar for best director for Life of Pi&quot;&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;// undefined&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Unlike the previous examples, &lt;code class=&quot;highlighter-rouge&quot;&gt;forEach()&lt;/code&gt; is used to produce &lt;a href=&quot;http://en.wikipedia.org/wiki/Side_effect_%28computer_science%29&quot;&gt;“side effects”&lt;/a&gt;. Practically speaking, because the return value of &lt;code class=&quot;highlighter-rouge&quot;&gt;forEach()&lt;/code&gt; is always &lt;code class=&quot;highlighter-rouge&quot;&gt;undefined&lt;/code&gt;, it can only be used to change the state of or interact with other parts of the program. This may seem like a fine distinction to some, but the use of side effects is a hotly contested debate across many programming language communities.&lt;/p&gt;

&lt;p&gt;It is worth pointing out that &lt;code class=&quot;highlighter-rouge&quot;&gt;forEach()&lt;/code&gt; is actually &lt;a href=&quot;http://jsperf.com/foreach-vs-loop&quot;&gt;significantly slower&lt;/a&gt; than the &lt;code class=&quot;highlighter-rouge&quot;&gt;for (i = 0; i &amp;lt; x.length; i += 1) {}&lt;/code&gt; idiom. But for most purposes, &lt;code class=&quot;highlighter-rouge&quot;&gt;forEach()&lt;/code&gt; is a much more expressive way to iterate over collections.&lt;/p&gt;

&lt;p&gt;&lt;em&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/forEach&quot;&gt;MDN Documentation - Array.prototype.forEach()&lt;/a&gt;&lt;/em&gt;&lt;/p&gt;

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

&lt;p&gt;Iterating over arrays is a common task when coding in almost any language, and JavaScript is no exception. The above &lt;code class=&quot;highlighter-rouge&quot;&gt;Array.prototype&lt;/code&gt; iterators are all defined in the ES5 spec and are widely supported on most modern web browsers (including IE 9 and above). They are relatively straightforward to use and make coding in JavaScript more functional and expressive.&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/prototype&quot;&gt;MDN Array.prototype Documentation&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://colintoh.com/blog/5-array-methods-that-you-should-use-today&quot;&gt;Colin Toh - 5 Array Methods That You Should Be Using Now&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://www.2ality.com/2011/04/iterating-over-arrays-and-objects-in.html&quot;&gt;2ality - Iterating over arrays and objects in JavaScript&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 03 Jan 2015 20:55:19 +0000</pubDate>
        <link>http://callahan.io/blog/2015/01/03/array-iteration-methods-in-javascript</link>
        <guid isPermaLink="true">http://callahan.io/blog/2015/01/03/array-iteration-methods-in-javascript</guid>
        
        
      </item>
    
      <item>
        <title>88 mph With Flux and React</title>
        <description>&lt;p&gt;&lt;a href=&quot;https://github.com/facebook/react&quot;&gt;React.js&lt;/a&gt; has gained a lot of attention since it was open sourced by Facebook last year, and with its recent version 0.12 release, it appears that a version 1.0 may soon be on the horizon. React is a lightweight front end toolkit for handling the view layer of web applications that emphasizes a unidirectional data flow to simplify logic about state and data binding. Under the hood, React utilizes a virtual DOM, diffing this with the &lt;a href=&quot;http://www.w3.org/DOM/&quot;&gt;plain old DOM&lt;/a&gt; (PODOM) and rerendering the page with the minimal effort necessary to reflect the updated state of the application. This is an interesting abstraction that makes it easier to reason about state in an application and relieves the need for developers to directly manipulate the DOM.&lt;/p&gt;

&lt;p&gt;This year, Facebook introduced Flux, the application architecture they use for React apps. Flux is more of a pattern for separating concerns and organizing files in large React applications than it is a full-blown front end framework like Angular or Ember. Flux provides a roadmap for ensuring the unidirectional flow of data in apps and allows for more modular processing of state changes, event handling, and interfacing with external services.&lt;/p&gt;

&lt;p&gt;I think React in particular is relatively easy and intuitive to understand. It provides a sparse API that makes it quick to set up a few components, attach some event listeners to the DOM, and get an app up and running. &lt;a href=&quot;http://jsx.github.io/&quot;&gt;JSX&lt;/a&gt;, a language that serves up a sugary mix of HTML and interpolated JavaScript (it compiles to JavaScript), is a bit odd at first. It’s quite easy to get used to though, and remarkably it totally relieves you from the need to do string concatenation, which is a big plus.&lt;/p&gt;

&lt;p&gt;Flux, on the other hand, takes a bit more time to fully grok. The conceit is simple: all data flows in one direction. But as I had previously primarily developed apps using the MVC architecture, Flux was a bit of a tough nut to crack.&lt;/p&gt;

&lt;p&gt;In this blog post, I hope to make it clear how to get started using Flux in a React application.&lt;/p&gt;

&lt;h3 id=&quot;conceptual-model&quot;&gt;Conceptual Model&lt;/h3&gt;

&lt;p&gt;Before I get into building the example app, it’s important to take a moment to think about the big picture of Flux. Luckily, there is one phenomenal chart that shows how all of the pieces work together:&lt;/p&gt;

&lt;p&gt;&lt;img src=&quot;http://facebook.github.io/react/img/blog/flux-diagram.png&quot; alt=&quot;diagram&quot; /&gt;&lt;/p&gt;

&lt;p&gt;The key parts of a Flux application are:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Actions&lt;/li&gt;
  &lt;li&gt;Dispatcher&lt;/li&gt;
  &lt;li&gt;Stores&lt;/li&gt;
  &lt;li&gt;Controller-View&lt;/li&gt;
  &lt;li&gt;Views&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Lesser roles are played by:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;Constants&lt;/li&gt;
  &lt;li&gt;Utils&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/rackt/react-router&quot;&gt;Router&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Keep in mind, this is all on the front end. React and Flux were explicitly intended to be back end agnostic. Plug in your favorite database and back end framework at will, should the need arise.&lt;/p&gt;

&lt;h3 id=&quot;architecture&quot;&gt;Architecture&lt;/h3&gt;

&lt;p&gt;Let’s say we want to build a small app that keeps track of the speed of Doc Brown’s DeLorean from &lt;em&gt;Back to the Future&lt;/em&gt;, and lets users know if the flux capacitor has been activated yet – the deciding factor of whether or not time travel is possible at their current speed. Feel free to follow along with the project repo on &lt;a href=&quot;https://github.com/callahanchris/bttf&quot;&gt;github&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Each of the key parts mentioned above gets their own folder in the file directory structure. A barebones Flux and React app (i.e. exclusively HTML, CSS, and JS files) should look something like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;.
├── css
|   └── styles.css
├── js
|   ├── actions
|   |   └── DeLoreanActionCreators.js
|   ├── components
|   |   ├── Accelerator.js
|   |   ├── DeLorean.js
|   |   ├── ImageSection.js
|   |   └── Speedometer.js
|   ├── constants
|   |   └── AppConstants.js
|   ├── dispatcher
|   |   └── AppDispatcher.js
|   ├── stores
|   |   └── DeLoreanStore.js
|   ├── app.js
|   └── bundle.js (this will be compiled automatically)
├── .gitignore
├── index.html
└── package.json
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I’ll use NPM for a package manager here. It is also &lt;a href=&quot;http://facebook.github.io/react/downloads.html&quot;&gt;easy&lt;/a&gt; to drop in a link to Facebook’s CDN or download React. Be aware that this does not include Flux, and with larger applications it makes sense to use a package manager where we can pull in several dependencies.&lt;/p&gt;

&lt;p&gt;Here’s the &lt;code class=&quot;highlighter-rouge&quot;&gt;package.json&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;language-json highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;name&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;bttf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;version&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;0.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;description&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Back to the Future-themed Flux + React app&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;repository&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;https://github.com/callahanchris/bttf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;main&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;js/app.js&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;dependencies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;flux&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^2.0.1&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;object-assign&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^1.0.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;react&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^0.12.1&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;devDependencies&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;browserify&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^6.3.2&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;reactify&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^0.17.0&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;watchify&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;^2.1.1&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;scripts&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;watch&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;watchify -o js/bundle.js -v -d .&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;build&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;browserify js/app.js -o js/bundle.js&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;author&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Chris Callahan&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;browserify&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;transform&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;&lt;span class=&quot;w&quot;&gt; &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
      &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;reactify&quot;&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
    &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
  &lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;w&quot;&gt;
&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;index.html&lt;/code&gt; file:&lt;/p&gt;
&lt;div class=&quot;language-html highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;cp&quot;&gt;&amp;lt;!DOCTYPE html&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;html&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;head&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;meta&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;charset=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;utf-8&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;title&amp;gt;&lt;/span&gt;88 mph With Flux and React&lt;span class=&quot;nt&quot;&gt;&amp;lt;/title&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;link&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;rel=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;stylesheet&quot;&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;href=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;css/styles.css&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/head&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;body&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;section&lt;/span&gt; &lt;span class=&quot;na&quot;&gt;id=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;bttf&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/section&amp;gt;&lt;/span&gt;
    &lt;span class=&quot;nt&quot;&gt;&amp;lt;script &lt;/span&gt;&lt;span class=&quot;na&quot;&gt;src=&lt;/span&gt;&lt;span class=&quot;s&quot;&gt;&quot;js/bundle.js&quot;&lt;/span&gt;&lt;span class=&quot;nt&quot;&gt;&amp;gt;&amp;lt;/script&amp;gt;&lt;/span&gt;
  &lt;span class=&quot;nt&quot;&gt;&amp;lt;/body&amp;gt;&lt;/span&gt;
&lt;span class=&quot;nt&quot;&gt;&amp;lt;/html&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and the &lt;code class=&quot;highlighter-rouge&quot;&gt;js/app.js&lt;/code&gt; file to bootstrap this app:&lt;/p&gt;
&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'react'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLorean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'./components/Delorean'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;App&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
  &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;DeLorean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;document&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getElementById&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'bttf'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;For now we’ll use just one CSS file, &lt;code class=&quot;highlighter-rouge&quot;&gt;css/styles.css&lt;/code&gt;. However, if the app gets big enough we might want to make the CSS more modular. One way we could do this is by using individual CSS files for each React component, (e.g. &lt;code class=&quot;highlighter-rouge&quot;&gt;css/Accelerator.css&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;css/DeLorean.css&lt;/code&gt;, etc.).&lt;/p&gt;

&lt;h3 id=&quot;writing-the-app-the-flux-way&quot;&gt;Writing the App… The Flux Way&lt;/h3&gt;

&lt;p&gt;Although the actions are at the top of the foodchain, it helps to conceptualize the flow of a Flux app starting from the View layer.&lt;/p&gt;

&lt;p&gt;At the top level of the View layer we have the “Controller-View”. For our purposes, this will be the DeLorean component that will wrap the entire application. The Controller-View is responsible for registering event listeners with the Stores, retrieving state from the Stores when the Stores emit an event, rerending the application with this new state using &lt;code class=&quot;highlighter-rouge&quot;&gt;this.setState()&lt;/code&gt;, and passing the state down to nested components through props.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// js/components/DeLorean.js&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'react'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Accelerator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'./Accelerator'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ImageSection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'./ImageSection'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Speedometer&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'./Speedometer'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'../stores/DeLoreanStore'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLorean&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;getInitialState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;componentDidMount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;addChangeListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_onChange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;componentWillUnmount&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;removeChangeListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;_onChange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;fluxCapacitorActivated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;88&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;delorean&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ImageSection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;fluxCapacitorActivated&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Accelerator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;/&amp;gt;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Speedometer&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;state&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt; &lt;span class=&quot;sr&quot;&gt;/&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;_onChange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;setState&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;getSpeed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()})&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLorean&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Say that the Accelerator component contains a &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;button&amp;gt;&lt;/code&gt; element. Unable to resist the temptation, a user clicks the button. This triggers the &lt;code class=&quot;highlighter-rouge&quot;&gt;onClick&lt;/code&gt; event handler we have embedded in this button, which calls the &lt;code class=&quot;highlighter-rouge&quot;&gt;handleClick&lt;/code&gt; method defined on the Accelerator component.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// js/components/Accelerator.js&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'react'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLoreanActionCreators&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'../actions/DeLoreanActionCreators'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Accelerator&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;React&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;createClass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;handleClick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;DeLoreanActionCreators&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;accelerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;// hard-coded to show how data flows through Flux&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;render&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;
      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;div&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;className&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'accelerator'&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;
        &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;button&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;onClick&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;=&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;handleClick&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;gt;&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Activate&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;the&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Flux&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Capacitor&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/button&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;      &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/div&lt;/span&gt;&lt;span class=&quot;err&quot;&gt;&amp;gt;
&lt;/span&gt;    &lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Accelerator&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This method sends a message to an Action Creator. Action Creators supply an API of accepted methods that can be invoked by components, and are also the place where information can break out of the Flux loop and communicate via &lt;a href=&quot;https://developer.mozilla.org/en-US/docs/Web/API/XMLHttpRequest&quot;&gt;XHR&lt;/a&gt; with the back end, external APIs, a database, etc. In the case of this app, it would be a bit contrived to ping an API or a back end, so I will keep the DeLoreanActionCreators file super simple and handle the logic in the DeLoreanStore.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// js/actions/DeLoreanActionCreators.js&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AppDispatcher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'../dispatcher/AppDispatcher'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionTypes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'../constants/AppConstants'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ActionTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;accelerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;AppDispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;handleViewAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ACCELERATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;mph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mph&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Action Creators can pass on any updated state they receive from the components to the Dispatcher along with a set action type. Typicially the name of the invoked method on the Action Creator mirrors the name of the action type. Action types are listed in the constants folder.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// js/constants/AppConstants.js&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;ActionTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;ACCELERATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'ACCELERATE'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;PayloadSources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;SERVER_ACTION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'SERVER_ACTION'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
    &lt;span class=&quot;na&quot;&gt;VIEW_ACTION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'VIEW_ACTION'&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This set of SCREAMING_CAMEL_CASE constants serves as the one definitive source of what actions are legal in the Flux application. Don’t overthink this – the sole purpose of the constants folder is for looking up constants. If the app gets large enough, you can get more modular in how you classify the constants, but at the end of the day all you want to know is what exactly are the officially sanctioned actions in this app.&lt;/p&gt;

&lt;p&gt;Next, the AppDispatcher receives the &lt;code class=&quot;highlighter-rouge&quot;&gt;handleViewAction()&lt;/code&gt; message along with the data above, which is referred to as the method argument &lt;code class=&quot;highlighter-rouge&quot;&gt;action&lt;/code&gt; below. The AppDispatcher is a singleton in the Flux app and has two main functions: forwarding the data it receives from the actions to all stores, and keeping track of the callbacks registered by stores.&lt;/p&gt;

&lt;p&gt;The AppDispatcher typically responds to messages sent from the Action Creators by calling the &lt;code class=&quot;highlighter-rouge&quot;&gt;dispatch()&lt;/code&gt; method on itself.&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// js/dispatcher/AppDispatcher.js&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Dispatcher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'flux'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;Dispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PayloadSources&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'../constants/AppConstants'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;PayloadSources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;assign&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'object-assign'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AppDispatcher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;k&quot;&gt;new&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;Dispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(),&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;handleViewAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PayloadSources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;VIEW_ACTION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;handleServerAction&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;payload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;source&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;PayloadSources&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;SERVER_ACTION&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt;
      &lt;span class=&quot;na&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;
    &lt;span class=&quot;p&quot;&gt;};&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AppDispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Dead simple. I think the choice of wording here was good, as it’s just like an emergency dispatcher that broadcasts messages to EMTs in the field and keeps track of who’s on duty.&lt;/p&gt;

&lt;p&gt;Creating Dispatchers used to require a lot of boilerplate code, but a canonical Dispatcher has recently been packaged up as part of the Flux NPM module. Check out the Dispatcher’s &lt;a href=&quot;http://facebook.github.io/flux/docs/dispatcher.html&quot;&gt;seriously simple builtin API&lt;/a&gt; in the offical documentation to see what goes on under the hood here.&lt;/p&gt;

&lt;p&gt;In a front end app, Stores are responsible for the logic that we typically associate with a model on the back end. Stores inherit from the prototype of node’s EventEmitter, and are responsible for consuming the data passed down from the dispatcher, changing its state internally, and emitting an event which forces the whole app to update its state.&lt;/p&gt;

&lt;p&gt;As I mentioned above, Stores also are required to register their callbacks with the AppDispatcher. The callback takes a payload as its argument, and then uses a &lt;code class=&quot;highlighter-rouge&quot;&gt;switch&lt;/code&gt; statement to determine what actions to take based on the action type listed in the payload. (This action type is the same constant originally defined by the DeLoreanActionCreators way back when.)&lt;/p&gt;

&lt;div class=&quot;language-javascript highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;// js/stores/DeLoreanStore.js&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AppDispatcher&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'../dispatcher/AppDispatcher'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionTypes&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'../constants/AppConstants'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;ActionTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EventEmitter&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'events'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;assign&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;require&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;'object-assign'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;CHANGE_EVENT&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'change'&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;assign&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;({},&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;EventEmitter&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;prototype&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;na&quot;&gt;emitChange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;emit&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CHANGE_EVENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;addChangeListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;on&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CHANGE_EVENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;removeChangeListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;this&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;removeListener&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;CHANGE_EVENT&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;callback&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;},&lt;/span&gt;

  &lt;span class=&quot;na&quot;&gt;getSpeed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;()&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;return&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_speed&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;dispatchToken&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;AppDispatcher&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;register&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;kd&quot;&gt;var&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;payload&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;switch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;type&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;ActionTypes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;na&quot;&gt;ACCELERATE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;_accelerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;action&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;);&lt;/span&gt;
    &lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;emitChange&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;();&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;break&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;

  &lt;span class=&quot;nl&quot;&gt;default&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;:&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;// noop&lt;/span&gt;
  &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;});&lt;/span&gt;

&lt;span class=&quot;kd&quot;&gt;function&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;_accelerate&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;mph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;
  &lt;span class=&quot;nx&quot;&gt;_speed&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;mph&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;

&lt;span class=&quot;nx&quot;&gt;module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nx&quot;&gt;exports&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nx&quot;&gt;DeLoreanStore&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Stores are the one place in a Flux application where state is officially defined. In a simple case, this may just be a running tally of how many times a button was clicked. Based on the action type, the Store’s public methods will utilize private methods to update its privately held data. Finally, it emits a ‘change’ event, and it’s work is done.&lt;/p&gt;

&lt;p&gt;Now we’re back in React’s View layer, but not so fast – the state of our application has changed! When the DeLorean component (our Controller-View) receives the new state from the DeLoreanStore, it calls its &lt;code class=&quot;highlighter-rouge&quot;&gt;setState()&lt;/code&gt; method. This automatically triggers its &lt;code class=&quot;highlighter-rouge&quot;&gt;render()&lt;/code&gt; method, which in turn triggers the &lt;code class=&quot;highlighter-rouge&quot;&gt;render()&lt;/code&gt; methods of all of its nested components, and it’s turtles all the way down.&lt;/p&gt;

&lt;p&gt;All components in the app now have access to the data in its current state, and await further instructions.&lt;/p&gt;

&lt;h3 id=&quot;closing-thoughts&quot;&gt;Closing Thoughts&lt;/h3&gt;

&lt;p&gt;It took me a couple weeks, but I finally feel like I’m understanding Flux, and I really like it! It provides a different way of reasoning about state and data flow in JavaScript applications. React is super straightforward, and as it approaches version 1.0, it is doing what it can to make its API &lt;a href=&quot;https://www.youtube.com/watch?v=4anAwXYqLG8&quot;&gt;even MORE simple&lt;/a&gt; as well as compliant with new ES6 (and even ES7!) features. I’m looking forward to delving into different libraries like RxJS and Immutable.js that take the ideas of functional reactive programming to the next level.&lt;/p&gt;

&lt;p&gt;Please check out the full code of my sample app on &lt;a href=&quot;https://github.com/callahanchris/bttf&quot;&gt;github&lt;/a&gt;!&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/flux/docs/overview.html&quot;&gt;Flux Overview&lt;/a&gt; – From the official documentation.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=nYkdrAPrdcw&quot;&gt;Jing Chen’s Original Flux Presentation&lt;/a&gt; – There’s some good info about React in here as well, but the Flux part is from 10 to 24 minutes in.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://www.youtube.com/watch?v=i__969noyAM&quot;&gt;React and Flux: Building Applications with a Unidirectional Data Flow&lt;/a&gt; – Good talk by Bill Fisher and Jing Chen where they go through an example chat application in Flux and React.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/facebook/flux/tree/master/examples/flux-chat/&quot;&gt;Flux Chat Example App on Github&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://facebook.github.io/react/blog/2014/07/30/flux-actions-and-the-dispatcher.html&quot;&gt;Flux: Actions and the Dispatcher&lt;/a&gt; – Helpful post by Bill Fisher going into a bit more detail about the Dispatcher, Actions, and Action Creators.&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Mon, 24 Nov 2014 03:41:11 +0000</pubDate>
        <link>http://callahan.io/blog/2014/11/24/88-mph-with-flux-and-react</link>
        <guid isPermaLink="true">http://callahan.io/blog/2014/11/24/88-mph-with-flux-and-react</guid>
        
        
      </item>
    
      <item>
        <title>Behind the Scenes of the 'Has Many' Active Record Association</title>
        <description>&lt;p&gt;In &lt;em&gt;The Rails 4 Way&lt;/em&gt;, Obie Fernandez describes what happens when you “wire up” associations (like &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;belongs_to&lt;/code&gt;) between Active Record models:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;When these relationship declarations are executed, Rails uses some metaprogramming magic to dynamically add code to your models. In particular, proxy collection objects are created that let you manipulate the relationship easily.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;– The Rails 4 Way, page 181&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;What exactly is this “metaprogramming magic” that goes on behind the scenes? In this blog post, I hope to uncover exactly what happens when &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; is used in an Active Record model.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;TL;DR:&lt;/strong&gt; When a class inherits from &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Base&lt;/code&gt;, it gets access to a large amount of class and instance methods, including the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; class method. When &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; is called on a class, a  &lt;code class=&quot;highlighter-rouge&quot;&gt;GeneratedAssociationMethods&lt;/code&gt; module is created on the fly and mixed into the class. A number of instance methods are then defined on this module (these vary depending on the type of association). These methods allow the original class to access and manipulate objects from the associated class passed as an symbol argument to the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method. Pretty magical if you ask me.&lt;/p&gt;

&lt;h3 id=&quot;diving-into-the-source-code&quot;&gt;Diving into the Source Code&lt;/h3&gt;

&lt;p&gt;The Rails source code has always been intimidating for me. There’s a ton of “metaprogramming magic” going on under the hood that appears incomprehensible or esoteric to a beginner. Though it’s all written in Ruby, which I feel reasonably comfortable with, I’m a total noob when it comes to metaprogramming, so my previous attempts to read the Rails source code have not gone very far.&lt;/p&gt;

&lt;p&gt;I try not to feel too bad about this. I’ve only been coding for about six months, and Rails has been constantly developed over the last ten years by some of the best programmers out there.&lt;/p&gt;

&lt;p&gt;My first step was to go the source: &lt;a href=&quot;https://github.com/rails/rails&quot;&gt;the Rails source code&lt;/a&gt;, that is. I cloned the master branch down to my computer, and started digging in.&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;git clone git@github.com:rails/rails.git
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I started to feel differently about the code once it was on my local machine. Suddenly I felt like I had more control over the code, just as I would with any other Ruby files open in Sublime Text on my computer. Rather than getting distracted by the complexity and sheer magnitude of the Rails codebase, I relied on techniques that I was already confident with and worked my way through from there.&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;NOTE:&lt;/strong&gt; I have pinned the links down to a commit in the Rails 4.1.4 era (when this post was written). Plenty of changes have been made since then, so be sure check out the latest version of the repo and investigate the code for yourself!&lt;/p&gt;

&lt;h3 id=&quot;starting-with-what-i-know&quot;&gt;Starting With What I Know&lt;/h3&gt;

&lt;p&gt;Let’s make a basic Rails app using &lt;em&gt;Game of Thrones&lt;/em&gt; as its domain model. At first, I have two classes, &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;Character&lt;/code&gt;, both of which inherit from &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Base&lt;/code&gt;. I’d wire up the associations between these classes as such:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# app/models/house.rb&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;House&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;has_many&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:characters&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# app/models/character.rb&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Character&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;belongs_to&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:house&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This domain logic makes sense; in &lt;em&gt;Game of Thrones&lt;/em&gt;, characters often introduce themselves in the fashion “I am Arya of House Stark.” Arya can be said to &lt;em&gt;belong to&lt;/em&gt; House Stark, while House Stark can be said to &lt;em&gt;have many&lt;/em&gt; characters (a collection, if you will) associated with it.&lt;/p&gt;

&lt;p&gt;At this point, here’s what I know about the code in the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; model:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class inherits from &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Base&lt;/code&gt;. This gives the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class and instances of this class access to a number of methods defined in the numerous modules included in the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Base&lt;/code&gt; class. We can now say that the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class is an “Active Record model”, as opposed to a “plain old Ruby object”.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;In Rails, an Active Record model is automatically mapped to a table in the database (in this case &lt;code class=&quot;highlighter-rouge&quot;&gt;houses&lt;/code&gt;), and attributes (i.e. methods) are created in the model that correspond to each column in this database table. Similarly, each instance of an Active Record model “wraps” one row in this table. This is the key to Rails’s adaptation of the Active Record pattern – database logic is effectively encapsulated into methods on the model layer.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; is a “bareword”. In Ruby, barewords can only be local variables, method arguments, keywords (like &lt;code class=&quot;highlighter-rouge&quot;&gt;class&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;def&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;end&lt;/code&gt;), and method calls. In this context, it’s neither a local variable nor a method argument, and it’s certainly not a keyword. Therefore it must be a method.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;If &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; is a method, then in this context its receiver must be the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class. That makes &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; a class method. It could also be written as &lt;code class=&quot;highlighter-rouge&quot;&gt;self.has_many&lt;/code&gt;, but the receiver is implicit here so we don’t need to write &lt;code class=&quot;highlighter-rouge&quot;&gt;self&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;It then follows that &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt; is a method argument passed to the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method. Ruby allows you to leave off the parentheses surrounding method arguments, though it is generally good practice to keep the parentheses in when defining a method with arguments.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Knowing that &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; is a class method defined somewhere in Active Record helped to narrow things down. From here, it was very easy to track the method definition down by doing a global search for &lt;code class=&quot;highlighter-rouge&quot;&gt;def has_many&lt;/code&gt; on the codebase using &lt;code class=&quot;highlighter-rouge&quot;&gt;Command + Shift + f&lt;/code&gt; in Sublime Text! Only one result appeared – a &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations.rb#L1245&quot;&gt;two-line method&lt;/a&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::ClassMethods&lt;/code&gt; module:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;has_many&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HasMany&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_reflection&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;taking-it-one-line-at-a-time&quot;&gt;Taking it One Line at a Time&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method signature is actually quite straightforward. Also, there is a copious amount (~200 lines) of &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations.rb#L1054&quot;&gt;documentation&lt;/a&gt; directly above the method definition that describes what &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; is, gives examples of how to use it, details the methods that are added when a &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; association is declared, and describes what all of the method arguments it takes are.&lt;/p&gt;

&lt;p&gt;Here’s a quick rundown of the arguments that &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; can take:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt;: The only required method argument here. The name conventionally takes a symbol the plural form and references a collection embodied by another class. In our case, &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt; is passed in as the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; parameter. The &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt; collection refers to multiple instances of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Character&lt;/code&gt; class (or rows of the &lt;code class=&quot;highlighter-rouge&quot;&gt;characters&lt;/code&gt; table in the database) that we want to associate with one instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class. This is the one-to-many relationship that lets us know we should use the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; association to begin with.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;scope&lt;/code&gt;: Defaults to &lt;code class=&quot;highlighter-rouge&quot;&gt;nil&lt;/code&gt;. A scope must be an object with a &lt;code class=&quot;highlighter-rouge&quot;&gt;call&lt;/code&gt; method, so &lt;code class=&quot;highlighter-rouge&quot;&gt;lambda&lt;/code&gt;s are generally used here. Scopes can help you narrow in on a more targeted set of records to retrieve from the database. In our example, if we only wanted to associate living characters with their houses, we’d use the following scope:&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;House&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;has_many&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:characters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;-&amp;gt;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;where&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;deceased: &lt;/span&gt;&lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;(Though this might get complicated when dealing with the Iron Islands…)&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;options&lt;/code&gt;: Defaults to an empty hash. Here you can further customize the nature of the association. Some common options to pass here are &lt;code class=&quot;highlighter-rouge&quot;&gt;through: :join_table&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;dependent: :destroy&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;polymorphic: true&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;foreign_key: :uuid&lt;/code&gt;.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;amp;extension&lt;/code&gt;: Explicit block argument, as indicated by the ampersand. I have never used this before, but the comments &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations.rb#L1149&quot;&gt;suggest&lt;/a&gt; that association extensions are “useful for adding new finders, creators and other factory-type methods to be used as part of the association.”&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;To figure out the next line, I first tracked down the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::HasMany&lt;/code&gt; class, which is quite slim, containing just three one-line methods! Unfortunately, &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; is not one of these methods. I traversed up the inheritance hierarchy, from &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::HasMany&lt;/code&gt; to &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::CollectionAssociation&lt;/code&gt; and finally to &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::Association&lt;/code&gt;, where the class method &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; is &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations/builder/association.rb#L28&quot;&gt;defined&lt;/a&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;dangerous_attribute_method?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ArgumentError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;You tried to define an association named &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; on the model &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;, but &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;\&lt;/span&gt;
                         &lt;span class=&quot;s2&quot;&gt;&quot;this will conflict with a method &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt; already defined by Active Record. &quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;\&lt;/span&gt;
                         &lt;span class=&quot;s2&quot;&gt;&quot;Please choose a different association name.&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;create_builder&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;block&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;define_accessors&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;define_callbacks&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;define_validations&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;builder&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define_extensions&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::Association::build&lt;/code&gt; method takes 5 arguments. The latter four of these arguments are identical to those initially passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt;. The first method argument is referred to as &lt;code class=&quot;highlighter-rouge&quot;&gt;model&lt;/code&gt; in &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt;’s method signature. Inside the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method, the value passed as this argument is &lt;code class=&quot;highlighter-rouge&quot;&gt;self&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Given that the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method is inside the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::ClassMethods&lt;/code&gt; module, I assumed that somewhere along the line this module is being mixed into a class. The value of &lt;code class=&quot;highlighter-rouge&quot;&gt;self&lt;/code&gt; inside a class method is the class itself – that is, whichever class called the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method to begin with (in our case &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt;).&lt;/p&gt;

&lt;p&gt;I had a difficult time tracking down where, if anywhere, this module is mixed in to the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class. Then I had a stunning (and obvious) realization: this module is mixed in to &lt;em&gt;every single Active Record model!&lt;/em&gt; From here, it was easy to hunt down &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/base.rb#L304&quot;&gt;the offending code&lt;/a&gt; in – where else? – &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Base&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;ActiveRecord&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Base&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
    &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Associations&lt;/span&gt;
    &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now we know that in our example, &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt; are being passed as the &lt;code class=&quot;highlighter-rouge&quot;&gt;model&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; arguments to the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; method.&lt;/p&gt;

&lt;h3 id=&quot;locating-the-metaprogramming-magic&quot;&gt;Locating the “Metaprogramming Magic”&lt;/h3&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; method first checks if the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; parameter is “dangerous”, and if so it throws an error. The &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/attribute_methods.rb#L128&quot;&gt;comment&lt;/a&gt; above the &lt;code class=&quot;highlighter-rouge&quot;&gt;dangerous_attribute_name?&lt;/code&gt; method states that “a method name is ‘dangerous’ if it is already (re)defined by Active Record, but not by any ancestors. (So ‘puts’ is not dangerous but ‘save’ is.)”&lt;/p&gt;

&lt;p&gt;Barring any unforeseen danger, the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; method then passes all of its method arguments to the &lt;code class=&quot;highlighter-rouge&quot;&gt;create_builder&lt;/code&gt; method, which is called on an implicit receiver. In this context, &lt;code class=&quot;highlighter-rouge&quot;&gt;self&lt;/code&gt; is referring to the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::HasMany&lt;/code&gt; class. The &lt;code class=&quot;highlighter-rouge&quot;&gt;create_builder&lt;/code&gt; method checks that the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; argument passed to it (&lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt;) is a symbol, then instantiates a new instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::HasMany&lt;/code&gt; class. This object is stored as &lt;code class=&quot;highlighter-rouge&quot;&gt;builder&lt;/code&gt;, a local variable in the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; method above.&lt;/p&gt;

&lt;p&gt;Next, the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; instance method (different from the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; class method) is called on the &lt;code class=&quot;highlighter-rouge&quot;&gt;builder&lt;/code&gt; object. The &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; instance method takes a model (&lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt;) as a method argument.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;macro&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The only new thing here is &lt;code class=&quot;highlighter-rouge&quot;&gt;macro&lt;/code&gt;, which is a method &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations/builder/has_many.rb#L3&quot;&gt;defined&lt;/a&gt; on the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::HasMany&lt;/code&gt; model.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;macro&lt;/span&gt;
  &lt;span class=&quot;ss&quot;&gt;:has_many&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Reflections::create&lt;/code&gt; method &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L15&quot;&gt;delegates&lt;/a&gt; based on the &lt;code class=&quot;highlighter-rouge&quot;&gt;macro&lt;/code&gt; passed to it. In our case, it instantiates an instance of &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L570&quot;&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Reflection::HasManyReflection&lt;/code&gt; class&lt;/a&gt;, which inherits from &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L249&quot;&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Reflection::Association&lt;/code&gt; class&lt;/a&gt;. I’m still not totally clear what reflections in general do, but &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L41&quot;&gt;this bit of documentation&lt;/a&gt; was helpful:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Reflection enables interrogating of Active Record classes and objects about their associations and aggregations. This information can, for example, be used in a form builder that takes an Active Record object and creates input fields for all of the attributes depending on their type and displays the associations to other objects.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The value returned is this instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Reflection::HasManyReflection&lt;/code&gt; class, and the original method &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::Builder::HasMany::build&lt;/code&gt; class method stores this object to a local variable &lt;code class=&quot;highlighter-rouge&quot;&gt;reflection&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Once I knew what the &lt;code class=&quot;highlighter-rouge&quot;&gt;model&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;reflection&lt;/code&gt; local variables were, it was relatively easy to locate the &lt;code class=&quot;highlighter-rouge&quot;&gt;define_accessors&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;define_callbacks&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;define_validations&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;define_extensions&lt;/code&gt; methods, as they were all in &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations/builder/association.rb#L99&quot;&gt;the same file as the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; method&lt;/a&gt;. In this blog post, I’ll only get into the &lt;code class=&quot;highlighter-rouge&quot;&gt;define_accessors&lt;/code&gt; method.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Defines the setter and getter methods for the association&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# class Post &amp;lt; ActiveRecord::Base&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#   has_many :comments&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# end&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;#&lt;/span&gt;
&lt;span class=&quot;c1&quot;&gt;# Post.first.comments and Post.first.comments= methods are defined by this method...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define_accessors&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;model&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;generated_association_methods&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;define_readers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;define_writers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define_readers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;class_eval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;__LINE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
    def &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;(*args)
      association(:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;).reader(*args)
    end
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;  CODE&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define_writers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;class_eval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;__LINE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
    def &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;=(value)
      association(:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;).writer(value)
    end
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;  CODE&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This was it. After much searching, I had found the “metaprogramming magic” at the core of Active Record associations.&lt;/p&gt;

&lt;h3 id=&quot;interpreting-the-metaprogramming-magic&quot;&gt;Interpreting the “Metaprogramming Magic”&lt;/h3&gt;

&lt;p&gt;Again, I had to start with what I know here. Two method arguments are passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;define_accessors&lt;/code&gt;: &lt;code class=&quot;highlighter-rouge&quot;&gt;model&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;reflection&lt;/code&gt;. When the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; method calls &lt;code class=&quot;highlighter-rouge&quot;&gt;define_accessors&lt;/code&gt;, it uses the same names for these arguments. Back in the &lt;code class=&quot;highlighter-rouge&quot;&gt;build&lt;/code&gt; method, &lt;code class=&quot;highlighter-rouge&quot;&gt;model&lt;/code&gt; referred to the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; Active Record model, and &lt;code class=&quot;highlighter-rouge&quot;&gt;reflection&lt;/code&gt; referred to the instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Reflection::HasManyReflection&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Moving on to the next line, I found the &lt;code class=&quot;highlighter-rouge&quot;&gt;generated_association_methods&lt;/code&gt; method is called on &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; and the return value is stored in a local variable &lt;code class=&quot;highlighter-rouge&quot;&gt;mixin&lt;/code&gt;. I tracked down &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/core.rb#L194&quot;&gt;the method definition&lt;/a&gt; of &lt;code class=&quot;highlighter-rouge&quot;&gt;generated_association_methods&lt;/code&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Core::ClassMethods&lt;/code&gt; module, alongside classics such as &lt;code class=&quot;highlighter-rouge&quot;&gt;find&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;find_by&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;generated_association_methods&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@generated_association_methods&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;begin&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;const_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:GeneratedAssociationMethods&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Module&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;mod&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I was really stumped by this one. For one thing, I was distracted by the &lt;code class=&quot;highlighter-rouge&quot;&gt;begin...end&lt;/code&gt; block and the PascalCase symbol. I had to take a step back and remember this is just Ruby code! Soon, I realized that this method memoizes the value of a class instance variable &lt;code class=&quot;highlighter-rouge&quot;&gt;@generated_association_methods&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;As it turns out, &lt;code class=&quot;highlighter-rouge&quot;&gt;const_set&lt;/code&gt; is an instance method on the &lt;code class=&quot;highlighter-rouge&quot;&gt;Module&lt;/code&gt; class in &lt;a href=&quot;http://ruby-doc.org/core-2.1.3/Module.html#method-i-const_set&quot;&gt;the Ruby core library&lt;/a&gt;. &lt;code class=&quot;highlighter-rouge&quot;&gt;const_set&lt;/code&gt; takes two arguments: the first is a string or symbol that will be the name of the new constant you’re creating, and the second argument is an object that will be set to the value of this constant. The constant is then namespaced under the receiver of the &lt;code class=&quot;highlighter-rouge&quot;&gt;const_set&lt;/code&gt; message.&lt;/p&gt;

&lt;p&gt;In this case, &lt;code class=&quot;highlighter-rouge&quot;&gt;const_set&lt;/code&gt; has an implicit receiver (&lt;code class=&quot;highlighter-rouge&quot;&gt;self&lt;/code&gt;). It’s tempting to think that &lt;code class=&quot;highlighter-rouge&quot;&gt;self&lt;/code&gt; is the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Core::ClassMethods&lt;/code&gt; module, but as above, this module is actually mixed in to the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class when we have it inherit from &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Base&lt;/code&gt;. The receiver here is actually &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt;. Thus, this method creates a new module in the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; namespace: &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt;. (Note that &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt; is the return value here, but if we were assigning pretty much anything but a new class or module as &lt;code class=&quot;highlighter-rouge&quot;&gt;GeneratedAssociationMethods&lt;/code&gt;’s value here, the return value would be that value.)&lt;/p&gt;

&lt;p&gt;On the next line of this method, the &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt; module is included into the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class. This is pretty awesome – I had no idea that you could call &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt; from inside a class method. It totally makes sense though, as the receiver is the class itself, so the use of &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt; here is no different than the typical use of &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt; in the class namespace.&lt;/p&gt;

&lt;p&gt;Finally, the &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt; module is returned, and thus is set as the value of the &lt;code class=&quot;highlighter-rouge&quot;&gt;@generated_association_methods&lt;/code&gt; class instance variable. Back in the &lt;code class=&quot;highlighter-rouge&quot;&gt;define_accessors&lt;/code&gt; method, this constant is stored as the &lt;code class=&quot;highlighter-rouge&quot;&gt;mixin&lt;/code&gt; variable.&lt;/p&gt;

&lt;p&gt;Going on to the next line of the &lt;code class=&quot;highlighter-rouge&quot;&gt;define_accessors&lt;/code&gt; method, the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; message is passed to the &lt;code class=&quot;highlighter-rouge&quot;&gt;reflection&lt;/code&gt; variable (our instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Reflection::HasManyReflection&lt;/code&gt; class). This object has &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L176&quot;&gt;an &lt;code class=&quot;highlighter-rouge&quot;&gt;attr_reader&lt;/code&gt; for name&lt;/a&gt;, which is &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L191&quot;&gt;set upon initialization&lt;/a&gt;. If it’s not too far a stretch back to remember, the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; attribute here is set to the original &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; passed as the first argument of the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method. A refresher:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;House&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;ActiveRecord&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;Base&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;has_many&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:characters&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; is simply &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt;!&lt;/p&gt;

&lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;define_accessors&lt;/code&gt; delegates to &lt;code class=&quot;highlighter-rouge&quot;&gt;define_readers&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;define_writers&lt;/code&gt;, passing &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt; as the &lt;code class=&quot;highlighter-rouge&quot;&gt;mixin&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; arguments to both of these methods. For simplicity, I will just focus on the &lt;code class=&quot;highlighter-rouge&quot;&gt;define_readers&lt;/code&gt; method.&lt;/p&gt;

&lt;h3 id=&quot;a-metaprogrammed-method&quot;&gt;A Metaprogrammed Method&lt;/h3&gt;

&lt;p&gt;From here, it is relatively clear to see what happens next. Let’s look at &lt;code class=&quot;highlighter-rouge&quot;&gt;define_readers&lt;/code&gt; again:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;define_readers&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;mixin&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;class_eval&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;lt;&amp;lt;-&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;CODE&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;__FILE__&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;__LINE__&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;
    def &lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;(*args)
      association(:&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;#{&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;si&quot;&gt;}&lt;/span&gt;&lt;span class=&quot;sh&quot;&gt;).reader(*args)
    end
&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;  CODE&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Aside of a few things in the first line of this method, this actually looks pretty straightforward: we’ve got a new method definition on our hands!&lt;/p&gt;

&lt;p&gt;On the first line of the method, &lt;code class=&quot;highlighter-rouge&quot;&gt;class_eval&lt;/code&gt; is called on the &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt; module. &lt;code class=&quot;highlighter-rouge&quot;&gt;class_eval&lt;/code&gt; is another instance method of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Module&lt;/code&gt; class in Ruby’s core library. It takes a string as an argument, as well as optional parameters for filename and line number. From &lt;a href=&quot;http://ruby-doc.org/core-2.1.3/Module.html#method-i-class_eval&quot;&gt;the documentation&lt;/a&gt;:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;&lt;strong&gt;class_eval(string [, filename [, lineno]]) → obj&lt;/strong&gt;&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;Evaluates the string or block in the context of &lt;strong&gt;mod&lt;/strong&gt;, except that when a block is given, constant/class variable lookup is not affected. This can be used to add methods to a class. &lt;code class=&quot;highlighter-rouge&quot;&gt;module_eval&lt;/code&gt; returns the result of evaluating its argument. The optional &lt;strong&gt;filename&lt;/strong&gt; and &lt;strong&gt;lineno&lt;/strong&gt; parameters set the text for error messages.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;As suspected, &lt;code class=&quot;highlighter-rouge&quot;&gt;class_eval&lt;/code&gt; allows us to add methods to a module or class. In this case, we are adding methods to the &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt; module. As this module has already been &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt;d in &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt;, these new methods can be accessed by instances of the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class.&lt;/p&gt;

&lt;p&gt;Let’s look at the parameters being passed to this method:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;string&lt;/code&gt;: The string being passed to the &lt;code class=&quot;highlighter-rouge&quot;&gt;class_eval&lt;/code&gt; method is a heredoc denoted by &lt;code class=&quot;highlighter-rouge&quot;&gt;&amp;lt;&amp;lt;-CODE ... CODE&lt;/code&gt;. The contents are a dynamic method definition that will look like this in the example we’re working with:&lt;/li&gt;
&lt;/ul&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;characters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;*&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:characters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;args&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;filename&lt;/code&gt;: I am still not entirely sure what &lt;code class=&quot;highlighter-rouge&quot;&gt;__FILE__&lt;/code&gt; precisely refers to, but I believe it refers to the current file. I am also not very clear about what this means in this context. My educated guess is that it refers to the &lt;code class=&quot;highlighter-rouge&quot;&gt;app/models/house.rb&lt;/code&gt; file, but really the method is being added to the &lt;code class=&quot;highlighter-rouge&quot;&gt;House::GeneratedAssociationMethods&lt;/code&gt; module, which was created dynamically and doesn’t have a file at all!&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;lineno&lt;/code&gt;: Again, I’m not too clear about this one. The &lt;a href=&quot;http://ruby-doc.org/docs/keywords/1.9/Object.html#method-i-__LINE__&quot;&gt;documentation&lt;/a&gt; is sparse here, only stating that &lt;code class=&quot;highlighter-rouge&quot;&gt;__LINE__&lt;/code&gt; refers to “The line number, in the current source file, of the current line.”&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;

&lt;p&gt;Almost there! We’ve now got our method definitions, but what do &lt;code class=&quot;highlighter-rouge&quot;&gt;association&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;reader&lt;/code&gt; refer to?&lt;/p&gt;

&lt;h3 id=&quot;associations-caching-and-reflections&quot;&gt;Associations, Caching, and Reflections&lt;/h3&gt;

&lt;p&gt;It turns out that &lt;code class=&quot;highlighter-rouge&quot;&gt;association&lt;/code&gt; is an &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations.rb#L150&quot;&gt;instance method&lt;/a&gt; of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations&lt;/code&gt; module.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;association&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;c1&quot;&gt;#:nodoc:&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;association_instance_get&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;nil?&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;raise&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;AssociationNotFoundError&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;unless&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;_reflect_on_association&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;association_class&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;association_instance_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;association&lt;/code&gt; method will pull the association specified by the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; argument passed to it (in our case &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt;)  out of the &lt;code class=&quot;highlighter-rouge&quot;&gt;@association_cache&lt;/code&gt; instance variable if it has already been loaded into memory. As &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/core.rb#L533&quot;&gt;defined&lt;/a&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Core&lt;/code&gt; module, &lt;code class=&quot;highlighter-rouge&quot;&gt;@association_cache&lt;/code&gt; is initialized to an empty Hash. Interestingly, this happens whenever you &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/core.rb#L266&quot;&gt;instantiate an Active Record object&lt;/a&gt; using the &lt;code class=&quot;highlighter-rouge&quot;&gt;House.new&lt;/code&gt; syntax!&lt;/p&gt;

&lt;p&gt;If the association is not in the &lt;code class=&quot;highlighter-rouge&quot;&gt;@association_cache&lt;/code&gt; (i.e. it hasn’t been loaded into memory), then the &lt;code class=&quot;highlighter-rouge&quot;&gt;association&lt;/code&gt; method checks whether the class where the association is defined (&lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt;) lists the associated class (&lt;code class=&quot;highlighter-rouge&quot;&gt;Character&lt;/code&gt;) as one of its &lt;code class=&quot;highlighter-rouge&quot;&gt;_reflections&lt;/code&gt; (a &lt;code class=&quot;highlighter-rouge&quot;&gt;class_attribute&lt;/code&gt; which is also &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L11&quot;&gt;initialized to an empty hash&lt;/a&gt;). The only way to &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/reflection.rb#L33&quot;&gt;add a reflection&lt;/a&gt; to this hash is through the &lt;code class=&quot;highlighter-rouge&quot;&gt;add_reflection&lt;/code&gt; module method. Remember where this is called?&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;has_many&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;nil&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{},&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Builder&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HasMany&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;build&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;scope&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;options&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;extension&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Reflection&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_reflection&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reflection&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the case of our domain model, the second line of the &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt; method will add the key &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;characters&quot;&lt;/code&gt; pointing to the value of our &lt;code class=&quot;highlighter-rouge&quot;&gt;reflection&lt;/code&gt; from above – the instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Reflection::HasManyReflection&lt;/code&gt; class – to the &lt;code class=&quot;highlighter-rouge&quot;&gt;_reflections&lt;/code&gt; hash.&lt;/p&gt;

&lt;p&gt;Let’s make an instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt; class.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;stark&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;House&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;surname: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Stark&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;sigil: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Direwolf&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;motto: &lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Winter is coming.&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; #&amp;lt;House id: 1, surname: &quot;Stark&quot;, sigil: &quot;Direwolf&quot;, motto: &quot;Winter is coming.&quot;, created_at: &quot;2014-10-09 20:05:01&quot;, updated_at: &quot;2014-10-09 20:05:01&quot;&amp;gt;&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;If we call &lt;code class=&quot;highlighter-rouge&quot;&gt;stark.characters&lt;/code&gt;, Rails first checks whether &lt;code class=&quot;highlighter-rouge&quot;&gt;&quot;characters&quot;&lt;/code&gt; is a key in &lt;code class=&quot;highlighter-rouge&quot;&gt;House&lt;/code&gt;’s &lt;code class=&quot;highlighter-rouge&quot;&gt;_reflections&lt;/code&gt; hash. If so, a new object is instantiated based on the type of this reflection – in the case of &lt;code class=&quot;highlighter-rouge&quot;&gt;has_many&lt;/code&gt;, it’s an instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::HasManyAssociation&lt;/code&gt; class. The &lt;code class=&quot;highlighter-rouge&quot;&gt;association&lt;/code&gt; method then calls &lt;code class=&quot;highlighter-rouge&quot;&gt;association_instance_set&lt;/code&gt;, passing &lt;code class=&quot;highlighter-rouge&quot;&gt;:characters&lt;/code&gt; and this instance of &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::HasManyAssociation&lt;/code&gt; as its parameters. This key value pair is then &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations.rb#L169&quot;&gt;added to the &lt;code class=&quot;highlighter-rouge&quot;&gt;@association_cache&lt;/code&gt; instance variable&lt;/a&gt;:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;association_instance_set&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@association_cache&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;association&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;association&lt;/code&gt; local variable is returned from the &lt;code class=&quot;highlighter-rouge&quot;&gt;association&lt;/code&gt; method above, and then is sent the &lt;code class=&quot;highlighter-rouge&quot;&gt;reader&lt;/code&gt; message, which is &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations/collection_association.rb#L29&quot;&gt;defined&lt;/a&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::CollectionAssociations&lt;/code&gt; class, the superclass of &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::HasManyAssociation&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;c1&quot;&gt;# Implements the reader method, e.g. foo.items for Foo.has_many :items&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;reader&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;force_reload&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;force_reload&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;klass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;uncached&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;reload&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;stale_target?&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;reload&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;vi&quot;&gt;@proxy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;CollectionProxy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;create&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;klass&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;a-return-value-at-the-end-of-the-tunnel&quot;&gt;A Return Value at the End of the Tunnel&lt;/h3&gt;

&lt;p&gt;Here on the last line of the &lt;code class=&quot;highlighter-rouge&quot;&gt;reader&lt;/code&gt; method was &lt;code class=&quot;highlighter-rouge&quot;&gt;@proxy&lt;/code&gt;, the final value that is returned by the newly minted &lt;code class=&quot;highlighter-rouge&quot;&gt;characters&lt;/code&gt; method. This &lt;code class=&quot;highlighter-rouge&quot;&gt;@proxy&lt;/code&gt; instance variable is also the one alluded to by Obie Fernandez when he says “proxy collection objects are created that let you manipulate the relationship easily.”&lt;/p&gt;

&lt;p&gt;Here is where it gets interesting: the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::CollectionProxy&lt;/code&gt; class &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/associations/collection_proxy.rb#L30&quot;&gt;inherits from&lt;/a&gt; &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Relation&lt;/code&gt;, which is the main class in Rails that deals with &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/relation.rb&quot;&gt;database operations&lt;/a&gt;. From here, we have to go all the way up the inheritance chain to the &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Delegation::ClassMethods&lt;/code&gt; module to find &lt;a href=&quot;https://github.com/rails/rails/tree/30ea1a70cba1124893b2479cb7f277cb260ddfcd/activerecord/lib/active_record/relation/delegation.rb#L105&quot;&gt;the &lt;code class=&quot;highlighter-rouge&quot;&gt;create&lt;/code&gt; method used here&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;Now when we call &lt;code class=&quot;highlighter-rouge&quot;&gt;stark.characters&lt;/code&gt;, we know without a shadow of a doubt what our return value will be!&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;stark&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;characters&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; [#&amp;lt;Character id: 1, name: &quot;Arya&quot;, age: 11, catchphrase: &quot;Stick them with the pointy end.&quot;, house_id: 1, created_at: &quot;2014-10-09 20:07:27&quot;, updated_at: &quot;2014-10-09 20:07:27&quot;&amp;gt;]&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Hmm. From inside the Rails console, this looks like an array. Let’s check out the class of this collection:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;stark&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;characters&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;class&lt;/span&gt;

&lt;span class=&quot;c1&quot;&gt;# =&amp;gt; Character::ActiveRecord_Associations_CollectionProxy&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Much better.&lt;/p&gt;

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

&lt;p&gt;This post was a good exercise for me to get more comfortable delving into the Rails source code, to begin to wrap my head around some of the legendary “Rails magic”, and to learn a bit more about metaprogramming in the wild. This is just the tip of the iceberg, but I no longer feel the Rails source code is untouchable. In fact, it’s all just a bunch of great Ruby code!&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;&lt;a href=&quot;https://github.com/rails/rails&quot;&gt;Read the Rails source code on Github.&lt;/a&gt; It’s terrifying and awesome.&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html&quot;&gt;Ruby on Rails API Documentation for &lt;code class=&quot;highlighter-rouge&quot;&gt;ActiveRecord::Associations::ClassMethods&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://ruby-doc.org/core-2.1.3/Module.html&quot;&gt;Ruby Core Documentation for Class: Module&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;https://leanpub.com/tr4w&quot;&gt;&lt;em&gt;The Rails 4 Way&lt;/em&gt;&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://devblog.avdi.org/2012/10/01/barewords/&quot;&gt;Ruby Tapas: Barewords&lt;/a&gt;&lt;/li&gt;
  &lt;li&gt;&lt;a href=&quot;http://blog.obiefernandez.com/content/2010/04/tr3w-highlights-activesupport-class-class-attribute.html&quot;&gt;&lt;code class=&quot;highlighter-rouge&quot;&gt;class_attribute&lt;/code&gt;s in Rails&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 08 Oct 2014 20:17:09 +0000</pubDate>
        <link>http://callahan.io/blog/2014/10/08/behind-the-scenes-of-the-has-many-active-record-association</link>
        <guid isPermaLink="true">http://callahan.io/blog/2014/10/08/behind-the-scenes-of-the-has-many-active-record-association</guid>
        
        
      </item>
    
      <item>
        <title>My Favorite Sublime Text Keyboard Shortcuts</title>
        <description>&lt;p&gt;Like many software developers, &lt;a href=&quot;http://www.sublimetext.com/&quot;&gt;Sublime Text&lt;/a&gt; is my preferred text editor. I do almost all of my coding and blogging in Sublime, and as such there are a few convenient keyboard shortcuts I’ve picked up along the way. &lt;em&gt;[Note: All keyboard shortcuts are for the OS X version of Sublime Text 2.02, YMMV.]&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;1-command--enter--new-line-below&quot;&gt;1. Command + Enter = New Line Below&lt;/h3&gt;

&lt;p&gt;Gone are the days of pressing Enter and accidentally cutting a line in half, then having to undo, then having to figure out a way to get the cursor to get to the end of the line before hitting Enter again. This shortcut has saved me a lot of energy – instead of worrying about where the cursor is on a line when hitting Enter, I only need to make sure that the cursor is on that line. Command + Enter takes care of the rest.&lt;/p&gt;

&lt;h3 id=&quot;2-command--shift--enter--new-line-above&quot;&gt;2. Command + Shift + Enter = New Line Above&lt;/h3&gt;

&lt;p&gt;A slight modification of the above, and an insanely useful shortcut. I didn’t realize how much I needed this shortcut until I started using it. It’s perfect if you write a couple of lines at the top of a file (e.g. a Ruby file)&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dog&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;
&lt;p&gt;then realize you need to do something above the first line (e.g. require another file).&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;require_relative&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'cat'&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Dog&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Zoom up to the top of the page with Command + Up arrow (not a Sublime-specific keyboard shortcut), then hit Command + Shift + Enter, and you’re ready to write.&lt;/p&gt;

&lt;p&gt;Another great use case of this for writing Ruby code is when you define a method. I will often instinctually write it like this:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;fetch&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;bone&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and then immediately realize I want to write the body of the method. Command + Shift + Enter has saved me many times here.&lt;/p&gt;

&lt;h3 id=&quot;3-command--shift--d--duplicate-current-line&quot;&gt;3. Command + Shift + d = Duplicate Current Line&lt;/h3&gt;

&lt;p&gt;Very straightforward and very useful. Simply duplicates the line you call the command on and places the new line below.&lt;/p&gt;

&lt;h3 id=&quot;4-control--shift--k--delete-current-line&quot;&gt;4. Control + Shift + k = Delete Current Line&lt;/h3&gt;

&lt;p&gt;Also straightforward, and a more efficient version of &lt;a href=&quot;https://www.youtube.com/watch?v=9LfmrkyP81M&quot;&gt;“the number one tool for improving code.”&lt;/a&gt;&lt;/p&gt;

&lt;h3 id=&quot;5-command--d--multiple-select-of-the-same-word&quot;&gt;5. Command + d = Multiple Select of the Same Word&lt;/h3&gt;

&lt;p&gt;Let’s say I’m refactoring my code and I decide to change the name of a method. I could do a global replacement with Command + Shift + f, but if I want to do a more fine-grained change and have more control over exactly what I’m highlighting and editing, I go with Command + d.&lt;/p&gt;

&lt;p&gt;What’s really cool about this is that Sublime gives you a cursor for each highlighted block of text! That means when you change the highlighted text in what you &lt;em&gt;think&lt;/em&gt; should be one place, &lt;em&gt;all&lt;/em&gt; of the highlighted texts change. This is the first demo on the Sublime Text website – check it out if you haven’t yet!&lt;/p&gt;

&lt;h3 id=&quot;6-command--highlight-text--multiple-select-of-different-words&quot;&gt;6. Command + Highlight Text = Multiple Select of Different Words&lt;/h3&gt;

&lt;p&gt;This one is similar to the Command + d, but is not restricted to highlighting repetitions of the same text. To get this to work, all you have to do is keep pressing the Command key and highlight different regions of text with the trackpad. As with the previous shortcut, this gets really powerful when combined with other keyboard shortcuts, like copy/paste.&lt;/p&gt;

&lt;p&gt;In Ruby, you might be setting several attributes of a class to values from a hash. If the keys of the hash happen to be named the same as the keys of the class’s attributes, then there is no need to type these out twice! If you start out with&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;import_dog_characteristics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;mood&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fur_color&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;favorite_toy&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;use Command + d to highlight all instances of &lt;code class=&quot;highlighter-rouge&quot;&gt;.&lt;/code&gt; in this method, then press the right arrow key so the three cursors are to the left of the attribute’s name. Next, use Alt + Shift + right arrow (not a Sublime-specific keyboard shortcut) to highlight the next word (Command + Shift + right arrow also works because the word is at the end of the line here) and copy it using Command + s. Press right arrow again to get to the cursors to the end of each line, type ` = hash[:` (note that Sublime autocloses the bracket!), and hit Command + v to paste in the attributes.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;import_dog_characteristics&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;fur_color&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:fur_color&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;favorite_toy&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;nb&quot;&gt;hash&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:favorite_toy&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now, we could probably do some refactoring here, but that’s another blog post!&lt;/p&gt;

&lt;h3 id=&quot;7-command--shift--p--set-syntax-highlighting&quot;&gt;7. Command + Shift + p = Set Syntax Highlighting&lt;/h3&gt;

&lt;p&gt;This shortcut actually opens up the Command Palette – a menu that includes a number of things like package controls and preference settings. Enter “ss” when the search bar pops up to jump down to the various “Set Syntax” options. The search functionality in Sublime Text is great at matching fuzzy queries, so if you just type “ssr” then hit Enter, the text in your file will have Ruby’s syntax highlighting.&lt;/p&gt;

&lt;p&gt;This is awesome if you are just sketching out some ideas in a file that you haven’t saved yet (on second thought, you might want to save that file!) or if you’re working in a bin or other file that doesn’t have an extension.&lt;/p&gt;

&lt;h3 id=&quot;8-command--t--find-file&quot;&gt;8. Command + t = Find File&lt;/h3&gt;

&lt;p&gt;Navigation between files can get a bit tricky when in a big project like a Rails app, and it’s easy to fall back on using the mouse to click through folders and open new files. Command + t lets you keep your hands on the keys by opening up a search bar to help you find the file you’re looking for. As with the previous shortcut, Sublime Text has great fuzzy matching for search queries, so you can find the file you’re looking for as easily as possible.&lt;/p&gt;

&lt;h3 id=&quot;9-alt--drag-mouse--select-rectangle-with-multiple-cursors&quot;&gt;9. Alt + Drag Mouse = Select Rectangle with Multiple Cursors&lt;/h3&gt;

&lt;p&gt;This one is cool, though admittedly I do not use it as often as the above shortcuts. Sometimes you want to get a cursor in the same column on 10 consecutive lines, or you want to select a 3 x 8 rectangle of text. Alt + drag mouse is the right tool for the job here. For this one to work, be sure that no text on the screen is highlighted, then hold Alt down, and finally drag the mouse over the desired text.&lt;/p&gt;

&lt;h3 id=&quot;10-control--command--up-arrow--move-line-up&quot;&gt;10. Control + Command + Up Arrow = Move Line Up&lt;/h3&gt;

&lt;p&gt;Great for quickly moving one or more lines up the page. Just highlight the lines you want to move, or make sure the cursor(s) is/are on the line(s) you want to move. Super convenient.&lt;/p&gt;

&lt;h3 id=&quot;11-control--command--down-arrow--move-line-down&quot;&gt;11. Control + Command + Down Arrow = Move Line Down&lt;/h3&gt;

&lt;p&gt;Same as the last shortcut, but moving in the opposite direction. These two shortcuts have saved me a lot of energy that would have been wasted copying/pasting and using the trackpad to highlight text. Keyboard shortcuts rock!&lt;/p&gt;

&lt;h3 id=&quot;12-command----indent-line-by-one-tab&quot;&gt;12. Command + [ = Indent Line by One Tab&lt;/h3&gt;

&lt;p&gt;Having nice, legible code depends to large extent on the formatting of the code. Though Ruby is not a whitespace-sensitive language, many other programming languages are. In any event, proper indentation is critical to writing legible code, and this a good shortcut to achieving this goal.&lt;/p&gt;

&lt;h3 id=&quot;13-command----unindent-line-by-one-tab&quot;&gt;13. Command + ] = Unindent Line by One Tab&lt;/h3&gt;

&lt;p&gt;Same as above, but going the other way. I’ll often use this in combination with Control + Command + down arrow when extracting a method, and these keyboard shortcuts make the process quick and simple!&lt;/p&gt;

&lt;h3 id=&quot;14-command----toggle-line-commenteduncommented&quot;&gt;14. Command + / = Toggle Line Commented/Uncommented&lt;/h3&gt;

&lt;p&gt;This shortcut comes in handy when testing out new ways to write old code. Instead of deleting the old, working code, simply comment it out, try out the new code, and then, if the new code works, use Control + Shift + k to delete the old code.&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://www.sublimetext.com/&quot;&gt;Sublime Text Official Website&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.shortcutfoo.com/&quot;&gt;Practice Sublime Text Shortcuts&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;Bonus for Rails developers: &lt;a href=&quot;https://github.com/eddorre/SublimeERB&quot;&gt;SublimeERB&lt;/a&gt;. This plugin makes one of the hardest parts of writing a Rails app (writing ERB tags) a piece of cake.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Wed, 24 Sep 2014 00:55:44 +0000</pubDate>
        <link>http://callahan.io/blog/2014/09/24/my-favorite-sublime-text-keyboard-shortcuts</link>
        <guid isPermaLink="true">http://callahan.io/blog/2014/09/24/my-favorite-sublime-text-keyboard-shortcuts</guid>
        
        
      </item>
    
      <item>
        <title>Getting Started With RSpec</title>
        <description>&lt;p&gt;RSpec is tool to test Ruby code using a very English-like syntax. RSpec is one of the most popular testing frameworks in the Ruby and Rails communities today, along with minitest (the default testing framework used in Rails 4) and Test::Unit.&lt;/p&gt;

&lt;p&gt;Testing is essential to writing reliable code. Not only does it establish a rapid feedback loop, but it also gives you the freedom to refactor your code to your heart’s content while ensuring that the code retains its original functionality.&lt;/p&gt;

&lt;h3 id=&quot;how-to-integrate-rspec-into-your-app&quot;&gt;How to Integrate RSpec Into Your App&lt;/h3&gt;

&lt;p&gt;It’s very easy to get started with RSpec. To download RSpec run&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;gem install rspec
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In a Ruby app, you can get RSpec up and running with&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rspec &lt;span class=&quot;nt&quot;&gt;--init&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This will make a &lt;code class=&quot;highlighter-rouge&quot;&gt;.rspec&lt;/code&gt; file in the root directory of the application and a &lt;code class=&quot;highlighter-rouge&quot;&gt;spec/&lt;/code&gt; directory containing a &lt;code class=&quot;highlighter-rouge&quot;&gt;spec_helper.rb&lt;/code&gt; file.&lt;/p&gt;

&lt;p&gt;To get RSpec integrated into a Rails app, add the following code to the &lt;code class=&quot;highlighter-rouge&quot;&gt;Gemfile&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;group&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:development&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:test&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;gem&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'rspec-rails'&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and run &lt;code class=&quot;highlighter-rouge&quot;&gt;bundle install&lt;/code&gt; to install the RSpec gems in the Rails app. Then run the following command to create the &lt;code class=&quot;highlighter-rouge&quot;&gt;.rspec&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;spec/spec_helper.rb&lt;/code&gt; files:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rails generate rspec:install
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Because Rails autogenerates a test suite through the &lt;code class=&quot;highlighter-rouge&quot;&gt;rails new&lt;/code&gt; command, it can also be helpful to tell Rails to not include these files with the &lt;code class=&quot;highlighter-rouge&quot;&gt;-T&lt;/code&gt; flag when creating a new app.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;rails new greatest_app_ever &lt;span class=&quot;nt&quot;&gt;-T&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now that RSpec is installed, you can run your specs from the command line with &lt;code class=&quot;highlighter-rouge&quot;&gt;rspec&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rspec
No examples found.

Finished &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0.00037 seconds &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;files took 0.11253 seconds to load&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
0 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;structuring-a-spec-file&quot;&gt;Structuring a Spec File&lt;/h3&gt;

&lt;p&gt;Let’s say I want to write a basic Ruby app that will keep track of some different espresso-based beverages. Here’s the file directory structure after running &lt;code class=&quot;highlighter-rouge&quot;&gt;rspec --init&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;espresso-maker/
|
|__ lib/
|   |
|   |__ espresso.rb
|
|__ spec/
|   |
|   |__ spec_helper.rb
|
|__ .rspec
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;So far these files are pretty empty. Here’s &lt;code class=&quot;highlighter-rouge&quot;&gt;espresso.rb&lt;/code&gt;:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Espresso&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I want to take a test-first approach to this app, so I’ll go ahead and set up a spec file to test the &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; class. Any file that ends in &lt;code class=&quot;highlighter-rouge&quot;&gt;_spec.rb&lt;/code&gt; will be run by the &lt;code class=&quot;highlighter-rouge&quot;&gt;rspec&lt;/code&gt; command, but it is best to name the spec files in the &lt;code class=&quot;highlighter-rouge&quot;&gt;model_name_spec.rb&lt;/code&gt; format. In the &lt;code class=&quot;highlighter-rouge&quot;&gt;spec&lt;/code&gt; directory, I made an &lt;code class=&quot;highlighter-rouge&quot;&gt;espresso_spec.rb&lt;/code&gt; file to house all the tests I’ll write for the &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; model.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;require_relative&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'spec_helper'&lt;/span&gt;

&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At the top of the &lt;code class=&quot;highlighter-rouge&quot;&gt;espresso_spec.rb&lt;/code&gt; file, I required the &lt;code class=&quot;highlighter-rouge&quot;&gt;spec_helper.rb&lt;/code&gt; file, where I will list all of the file dependencies so that they don’t clutter up this spec file. Then I opened a &lt;code class=&quot;highlighter-rouge&quot;&gt;describe&lt;/code&gt; block for the &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; class - all of the tests in this file should go inside this block. Note that it’s OK to use the constant &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; in this case, but generally you will pass in a string as an argument to the RSpec methods &lt;code class=&quot;highlighter-rouge&quot;&gt;describe&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;context&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;it&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;In order for the tests to run properly, I also need to add the following line to the &lt;code class=&quot;highlighter-rouge&quot;&gt;spec/spec_helper.rb&lt;/code&gt; file:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nb&quot;&gt;require_relative&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'../lib/espresso'&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Without this &lt;code class=&quot;highlighter-rouge&quot;&gt;require_relative&lt;/code&gt; statement, RSpec will not understand what &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; is and will throw an uninitialized constant NameError.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#name'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#ingredients'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'.country_of_origin'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Inside the &lt;code class=&quot;highlighter-rouge&quot;&gt;describe Espresso&lt;/code&gt; block, I opened a &lt;code class=&quot;highlighter-rouge&quot;&gt;describe&lt;/code&gt; block for each public method that will be part of &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt;’s API. These method-specific &lt;code class=&quot;highlighter-rouge&quot;&gt;describe&lt;/code&gt; blocks should use the &lt;code class=&quot;highlighter-rouge&quot;&gt;#method_name&lt;/code&gt; notation for instance methods and the &lt;code class=&quot;highlighter-rouge&quot;&gt;.method_name&lt;/code&gt; notation for class methods.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#name'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'is espresso'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#ingredients'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'one part espresso'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'.country_of_origin'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'is from Kenya'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Within each &lt;code class=&quot;highlighter-rouge&quot;&gt;describe&lt;/code&gt; block, I can open &lt;code class=&quot;highlighter-rouge&quot;&gt;it&lt;/code&gt; blocks that will contain the actual expectations to be tested. &lt;code class=&quot;highlighter-rouge&quot;&gt;it&lt;/code&gt; takes a terse (less than 40 characters) description of the specific expectation I’m setting on the method for this test as an argument.&lt;/p&gt;

&lt;p&gt;Inside of &lt;code class=&quot;highlighter-rouge&quot;&gt;it&lt;/code&gt; blocks, the RSpec 3 syntax uses the &lt;code class=&quot;highlighter-rouge&quot;&gt;expect&lt;/code&gt; method to set up an expectation.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;+&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In general, you pass an expression to be evaluated to the &lt;code class=&quot;highlighter-rouge&quot;&gt;expect&lt;/code&gt; method and chain &lt;code class=&quot;highlighter-rouge&quot;&gt;to&lt;/code&gt; to the end of this method. Then you call a matcher method and pass in the value you expect the argument passed to &lt;code class=&quot;highlighter-rouge&quot;&gt;expect&lt;/code&gt; to evaluate to. Some of the most common RSpec matcher methods are &lt;code class=&quot;highlighter-rouge&quot;&gt;eq&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;include&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;match&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;respond_to&lt;/code&gt;, all of which closely correspond to Ruby methods.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;([&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;2&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;]).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;Hello world, my name is Chris!&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/Hello world/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;an ordinary string&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;respond_to&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:upcase&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;writing-the-specs&quot;&gt;Writing the Specs&lt;/h3&gt;

&lt;p&gt;Now it’s time to write our first test!&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#name'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'is espresso'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;espresso&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;espresso&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here we’re instantiating a new &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; object and setting up an expectation that the &lt;code class=&quot;highlighter-rouge&quot;&gt;#name&lt;/code&gt; method will return the value “espresso” when it is sent to an instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; class. We run &lt;code class=&quot;highlighter-rouge&quot;&gt;rspec&lt;/code&gt; and the test fails.&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rspec

Espresso
  &lt;span class=&quot;c&quot;&gt;#name&lt;/span&gt;
    is espresso &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;FAILED - 1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;

Failures:

  1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Espresso#name is espresso
     Failure/Error: expect&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;espresso.name&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.to eq&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
     NoMethodError:
       undefined method &lt;span class=&quot;sb&quot;&gt;`&lt;/span&gt;name&lt;span class=&quot;s1&quot;&gt;' for #&amp;lt;Espresso:0x00000103131178&amp;gt;
     # ./spec/espresso_spec.rb:7:in `block (3 levels) in &amp;lt;top (required)&amp;gt;'&lt;/span&gt;

Finished &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0.00057 seconds &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;files took 0.11633 seconds to load&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
1 example, 1 failure

Failed examples:

rspec ./spec/espresso_spec.rb:5 &lt;span class=&quot;c&quot;&gt;# Espresso#name is espresso&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Now the cycle of “Red, Green, Refactor” can begin. We have a failing (red) test, now let’s do the minimum possible work to get the test to pass (green). Once we have green tests, then we can mercilessly refactor while ensuring the tests stay green, and thus the functionality of the code stays the same.&lt;/p&gt;

&lt;p&gt;Based on the error message above, I know the first step should be adding a &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; method to the &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; class.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Espresso&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Running &lt;code class=&quot;highlighter-rouge&quot;&gt;rspec&lt;/code&gt; again gives a bit more guidance about what the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; method should return:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Failures:

  1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Espresso#name is espresso
     Failure/Error: expect&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;espresso.name&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.to eq&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
       
       expected: &lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;
            got: nil
       
       &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;compared using &lt;span class=&quot;o&quot;&gt;==)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Let’s make the test go green!&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Espresso&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rspec

Espresso
  &lt;span class=&quot;c&quot;&gt;#name&lt;/span&gt;
    is espresso

Finished &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0.00158 seconds &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;files took 0.12372 seconds to load&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
1 example, 0 failures
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Success!&lt;/p&gt;

&lt;h3 id=&quot;introducing-contexts&quot;&gt;Introducing &lt;code class=&quot;highlighter-rouge&quot;&gt;context&lt;/code&gt;s&lt;/h3&gt;

&lt;p&gt;Now I want to have the &lt;code class=&quot;highlighter-rouge&quot;&gt;#name&lt;/code&gt; method return different results depending on whether or not the espresso has milk in it. I could just write a new &lt;code class=&quot;highlighter-rouge&quot;&gt;it '...'&lt;/code&gt; expectation inside of the &lt;code class=&quot;highlighter-rouge&quot;&gt;describe &quot;#name&quot;&lt;/code&gt; block, but this might get unwieldy in short order. Namespacing is important to writing readable, easy-to-follow tests. If there are many facets of a method to be tested, we can group the nested &lt;code class=&quot;highlighter-rouge&quot;&gt;it&lt;/code&gt; blocks inside of &lt;code class=&quot;highlighter-rouge&quot;&gt;context&lt;/code&gt; blocks.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;describe&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'#name'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'without milk'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'is espresso'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;espresso&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;espresso&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;context&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'with milk'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;it&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;'is macchiato'&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;espresso&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Espresso&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;espresso&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;add_milk&lt;/span&gt;
        &lt;span class=&quot;n&quot;&gt;expect&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;espresso&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;eq&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;macchiato&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Here I’ve written two &lt;code class=&quot;highlighter-rouge&quot;&gt;context&lt;/code&gt; blocks, one for an espresso with milk and one for an espresso without milk. In order to get the milk into the espresso, I’ve also included an &lt;code class=&quot;highlighter-rouge&quot;&gt;add_milk&lt;/code&gt; method – this should also be tested as part of &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt;’s API. Before getting the next test to pass, I fleshed out the &lt;code class=&quot;highlighter-rouge&quot;&gt;Espresso&lt;/code&gt; class a bit to support this new method.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;Espresso&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@milk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;false&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;add_milk&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;self&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;milk&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;kp&quot;&gt;true&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;kp&quot;&gt;private&lt;/span&gt;
    &lt;span class=&quot;nb&quot;&gt;attr_accessor&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:milk&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;has_milk?&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;milk&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The RSpec failure for the second test then read:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;Failures:

  1&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt; Espresso#name with milk is macchiato
     Failure/Error: expect&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;espresso.name&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;.to eq&lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;macchiato&quot;&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
       
       expected: &lt;span class=&quot;s2&quot;&gt;&quot;macchiato&quot;&lt;/span&gt;
            got: &lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;
       
       &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;compared using &lt;span class=&quot;o&quot;&gt;==)&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In order to get this test to pass, I implemented the simplest change possible to the &lt;code class=&quot;highlighter-rouge&quot;&gt;name&lt;/code&gt; method:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;has_milk?&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;?&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;macchiato&quot;&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;:&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;espresso&quot;&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;then ran &lt;code class=&quot;highlighter-rouge&quot;&gt;rspec&lt;/code&gt; and enjoyed the nicely namespaced RSpec output:&lt;/p&gt;

&lt;div class=&quot;language-bash highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;nv&quot;&gt;$ &lt;/span&gt;rspec

Espresso
  &lt;span class=&quot;c&quot;&gt;#name&lt;/span&gt;
    without milk
      is espresso
    with milk
      is macchiato

Finished &lt;span class=&quot;k&quot;&gt;in &lt;/span&gt;0.00147 seconds &lt;span class=&quot;o&quot;&gt;(&lt;/span&gt;files took 0.12149 seconds to load&lt;span class=&quot;o&quot;&gt;)&lt;/span&gt;
2 examples, 0 failures
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Going forward, I could also add &lt;code class=&quot;highlighter-rouge&quot;&gt;context&lt;/code&gt;s for things like “without ice” and “with ice”.&lt;/p&gt;

&lt;h3 id=&quot;next-steps&quot;&gt;Next Steps&lt;/h3&gt;

&lt;p&gt;This is a basic introduction to writing the first few tests of a Ruby app with RSpec, and is far from a complete resource. Already we can see that there is some repetition in the tests above (&lt;code class=&quot;highlighter-rouge&quot;&gt;espresso = Espresso.new&lt;/code&gt;) that should be abstracted out. RSpec has a number of convenient methods to help you DRY out your tests, such as &lt;code class=&quot;highlighter-rouge&quot;&gt;let&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;before&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;subject&lt;/code&gt;, and &lt;code class=&quot;highlighter-rouge&quot;&gt;it_behaves_like&lt;/code&gt;. There’s also clearly some more refactoring that can be done on the code itself – but now we have a safety net to fall back on when we start refactoring.&lt;/p&gt;

&lt;p&gt;For more comprehensive info about RSpec, check out the resources below!&lt;/p&gt;

&lt;h3 id=&quot;resources&quot;&gt;Resources&lt;/h3&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.relishapp.com/rspec&quot;&gt;Official RSpec Documentation&lt;/a&gt;&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;http://betterspecs.org/&quot;&gt;Better Specs&lt;/a&gt; - A collection of RSpec best practices&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;a href=&quot;https://www.codeschool.com/courses/testing-with-rspec&quot;&gt;Testing with RSpec on Code School&lt;/a&gt; - Still uses the RSpec 2 &lt;code class=&quot;highlighter-rouge&quot;&gt;should&lt;/code&gt; syntax, but otherwise a great intro to RSpec.&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Thu, 18 Sep 2014 15:56:23 +0000</pubDate>
        <link>http://callahan.io/blog/2014/09/18/getting-started-with-rspec</link>
        <guid isPermaLink="true">http://callahan.io/blog/2014/09/18/getting-started-with-rspec</guid>
        
        
      </item>
    
      <item>
        <title>China Map Project - Part 4: Introducing Polymorphism</title>
        <description>&lt;p&gt;&lt;em&gt;This the fourth and final post in a series about my recent side project, &lt;a href=&quot;http://amapofchina.herokuapp.com&quot;&gt;A Map of China&lt;/a&gt;. Check out the &lt;a href=&quot;http://callahan.io/blog/2014/09/11/china-map-project-part-1-nokogiri/&quot;&gt;first post&lt;/a&gt;, &lt;a href=&quot;http://callahan.io/blog/2014/09/11/china-map-project-part-2-bringing-the-map-to-life-with-jvectormap/&quot;&gt;second post&lt;/a&gt;, &lt;a href=&quot;http://callahan.io/blog/2014/09/12/china-map-project-part-3-refactoring-using-replace-method-with-method-object/&quot;&gt;third post&lt;/a&gt;, and the &lt;a href=&quot;https://github.com/callahanchris/china-map&quot;&gt;project repo&lt;/a&gt; on Github.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;the-road-to-polymorphism&quot;&gt;The Road to Polymorphism&lt;/h3&gt;

&lt;p&gt;When I started this project, I set out to make an interactive map that displayed a variety of data about the Chinese provinces. But this very premise – mapping Chinese provinces – turned out to be far more nuanced and complex than I realized at the outset.&lt;/p&gt;

&lt;p&gt;Technically speaking, China has 22 provinces (e.g. Shaanxi, Guangdong), 5 autonomous regions (e.g. Tibet, Inner Mongolia), 4 municipalities (Beijing, Shanghai, Chongqing, and Tianjin), and 2 special administrative regions (SARs) (Hong Kong and Macau). &lt;em&gt;[Note: Any issues pertaining to Taiwan fall outside the scope of this project.]&lt;/em&gt;&lt;/p&gt;

&lt;p&gt;Originally, I had named the main model in my Rails app &lt;code class=&quot;highlighter-rouge&quot;&gt;Province&lt;/code&gt;, but later decided that &lt;code class=&quot;highlighter-rouge&quot;&gt;Region&lt;/code&gt; would be more suitable. I considered breaking up the &lt;code class=&quot;highlighter-rouge&quot;&gt;Region&lt;/code&gt; model into several smaller models (i.e. &lt;code class=&quot;highlighter-rouge&quot;&gt;Province&lt;/code&gt;, &lt;code class=&quot;highlighter-rouge&quot;&gt;AutonomousRegion&lt;/code&gt;, etc.), but I wanted the data output from the JSON API to all be standardized and accessible from one endpoint, so I kept all regions contained in one model.&lt;/p&gt;

&lt;p&gt;The issue of polymorphism came up when I realized that I was using a large number of conditional checks on the region’s name in my Wikipedia scraping code. The most prominent among these was the following:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;While I didn’t have a &lt;code class=&quot;highlighter-rouge&quot;&gt;SpecialAdministrativeRegion&lt;/code&gt; model, this conditional logic more or less amounted to a type check that significantly bogged down the readability and clarity of my code.&lt;/p&gt;

&lt;p&gt;Recently I have been reading through &lt;a href=&quot;http://martinfowler.com/books/refactoringRubyEd.html&quot;&gt;&lt;em&gt;Refactoring: Ruby Edition&lt;/em&gt;&lt;/a&gt;, and found a refactoring that suited my needs in this case: Replace Type Code with Polymorphism.&lt;/p&gt;

&lt;h3 id=&quot;extract-method&quot;&gt;Extract Method&lt;/h3&gt;

&lt;p&gt;Before I was able to implement the Replace Type Code with Polymorphism refactoring, I needed to continue refactoring the lengthy &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; method in the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class from the &lt;a href=&quot;http://callahan.io/blog/2014/09/12/china-map-project-part-3-refactoring-using-replace-method-with-method-object/&quot;&gt;last post&lt;/a&gt;. Within the &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; method, I had been assigning about ten different pieces of data to the &lt;code class=&quot;highlighter-rouge&quot;&gt;Region&lt;/code&gt; objects and saving them to the database. In order to preserve the &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; API set up in the last post, I had &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; delegate to a number of smaller methods, which I removed from &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; using Extract Method.&lt;/p&gt;

&lt;p&gt;Quoting Martin Fowler:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;Extract Method is one of the most common refactorings I do. I look at a method that is too long or look at code that needs a comment to understand its purpose. I then turn that fragment of code into its own method.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;I prefer short, well-named methods for several reasons. First, it increases the chances that other methods can use a method when the method is finely grained. Second, it allows the higher-level methods to read more like a series of comments. Overriding also is easier when the methods are finely grained.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;– Refactoring: Ruby Edition, page 102&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;Extract Method is an incredibly useful and easy refactoring to undertake. The mechanics are as follows:&lt;/p&gt;

&lt;blockquote&gt;
1. Create a new method, and name it after the intention of the method (name it by what it does, not by how it does it).
&lt;br /&gt;
2. Copy the extracted code from the source method into the new target method.
&lt;/blockquote&gt;

&lt;p&gt;Steps 3-6 deal with handling local variables, which I already extracted out of &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; in the Replace Method with Method Object refactoring in the last post.&lt;/p&gt;

&lt;blockquote&gt;
7. Replace the extracted code in the source method with a call to the target method.
&lt;br /&gt;
8. Test.
&lt;br /&gt;
-- Refactoring: Ruby Edition, page 103
&lt;/blockquote&gt;

&lt;p&gt;In practice, I looked for chunks of code in the &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; method like this:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gdp_per_capita&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp_per_cap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_i&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gdp_per_capita&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp_per_cap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_i&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;then I copied the code out into its own method:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_gdp_per_cap&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gdp_per_capita&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp_per_cap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_i&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gdp_per_capita&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;gdp_per_cap&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;3&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;gsub&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;','&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s1&quot;&gt;''&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;to_i&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and replaced the original chunk of code with a call to the extracted method:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_gdp_per_cap&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I methodically went through the &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; method and used Extract Method until all logical units of work had been extracted. In the end, the &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; method had shrunk from almost 100 lines into this succinct delegator method:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_territorial_designation&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_lat_lng&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_capital&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_area_info&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_gdp_usd&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_gdp_cny&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_gdp_per_cap&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;assign_jvector_code&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;save&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;replace-type-code-with-polymorphism&quot;&gt;Replace Type Code with Polymorphism&lt;/h3&gt;

&lt;p&gt;With the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class now broken down into small methods, it was much easier to see how to implement the Replace Type Code with Polymorphism refactoring. Here are the mechanics for carrying out this refactoring:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Create a class to represent each type code variant.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Change the class that uses the type code into a module. Include the module into each of the new type classes.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Change the callers of the original class to create an instance of the desired type instead.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Test.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Choose one of the methods that use the type code. Override the method on one of the type classes.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Test.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Do the same for the other type classes, removing the method on the module when you’re done.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Test.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Repeat for the other methods that use the type code.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Test.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Remove the module if it no longer houses useful behavior.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;– Refactoring: Ruby Edition, page 226-227&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;In practice my execution was also a bit similar to the Replace Conditional with Polymorphism refactoring (&lt;em&gt;Refactoring: Ruby Edition&lt;/em&gt;, page 279-284).&lt;/p&gt;

&lt;p&gt;First I made classes for each regional classification, turned the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class into a module, and included the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; module in each class.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;module&lt;/span&gt; &lt;span class=&quot;nn&quot;&gt;RegionAssembler&lt;/span&gt;
  &lt;span class=&quot;c1&quot;&gt;# ...&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;ProvinceAssembler&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RegionAssembler&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;AutonomousRegionAssembler&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RegionAssembler&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;MunicipalityAssembler&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RegionAssembler&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;SARAssembler&lt;/span&gt;
  &lt;span class=&quot;kp&quot;&gt;include&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;RegionAssembler&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next I modified the &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; method in the &lt;code class=&quot;highlighter-rouge&quot;&gt;ChinaScraper&lt;/code&gt; class to appropriately call each of these new classes.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;scrape_all_regions&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nokogiri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;case&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Hong Kong&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Macau&quot;&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;SARAssembler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Beijing&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Chongqing&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Shanghai&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Tianjin&quot;&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;MunicipalityAssembler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;when&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Guangxi&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Inner Mongolia&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Ningxia&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Xinjiang&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;s2&quot;&gt;&quot;Tibet&quot;&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;AutonomousRegionAssembler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;no&quot;&gt;ProvinceAssembler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt; 
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then, one at a time, I began overriding the methods from the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; module in individual classes. I started doing this in the &lt;code class=&quot;highlighter-rouge&quot;&gt;SARAssembler&lt;/code&gt; class first because the Hong Kong and Macau Wikipedia pages had the most special cases that led to the overuse of conditionals in the first place.&lt;/p&gt;

&lt;p&gt;In practice, here’s how the overriding worked. I started with the &lt;code class=&quot;highlighter-rouge&quot;&gt;assign_territorial_designation&lt;/code&gt; method (extracted out of the &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; method above) in the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; module:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_territorial_designation&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr td a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/special/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; of &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;span.category a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I copied this method into the &lt;code class=&quot;highlighter-rouge&quot;&gt;SARAssembler&lt;/code&gt; class, removed all but one line, and slightly refactored the text selector.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_territorial_designation&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr td a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;
                                     &lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/special/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;
                                     &lt;span class=&quot;nf&quot;&gt;attributes&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;[&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;title&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;value&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
                                     &lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Then in the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; module, I was able to turn this method into a nice one-liner.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_territorial_designation&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;span.category a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;
                                     &lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;At this point, it became apparent that this method actually had two responsibilities: assigning the accurate text and making sure it was in title caps. There was a clear opportunity to extract a &lt;code class=&quot;highlighter-rouge&quot;&gt;title_caps&lt;/code&gt; method:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;title_caps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;string&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;I could then further simplify the &lt;code class=&quot;highlighter-rouge&quot;&gt;assign_territorial_designation&lt;/code&gt; method as such:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_territorial_designation&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;title_caps&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;span.category a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;This refactoring was particularly helpful for methods that applied to certain classes but not to others. Take for instance the &lt;code class=&quot;highlighter-rouge&quot;&gt;assign_capital&lt;/code&gt; method. Municipalities and SARs are cities, and therefore don’t have capitals. This method clearly doesn’t apply to them. Yet the original &lt;code class=&quot;highlighter-rouge&quot;&gt;assign_capital&lt;/code&gt; method spent a significant amount of effort checking whether or not it applied.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_capital&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;!&lt;/span&gt;&lt;span class=&quot;sx&quot;&gt;%w{ Beijing Chongqing Shanghai Tianjin Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;capital&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedtoprow a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the &lt;code class=&quot;highlighter-rouge&quot;&gt;SARAssembler&lt;/code&gt; and &lt;code class=&quot;highlighter-rouge&quot;&gt;MunicipalityAssembler&lt;/code&gt; classes, I overwrote this with an empty method:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_capital&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;and then was able to refactor the &lt;code class=&quot;highlighter-rouge&quot;&gt;assign_capital&lt;/code&gt; method in the module into a much simpler version:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;assign_capital&lt;/span&gt;
  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;capital&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedtoprow a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;0&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;In the end, I kept the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; module, as there would have been too much code duplication if I copied over all of the methods into each of the four classes. At 80 lines, the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; module is not exactly small, but the majority of its methods are one-liners, and the type checking is gone.&lt;/p&gt;

&lt;h3 id=&quot;the-final-step-for-now&quot;&gt;The Final Step (For Now…)&lt;/h3&gt;

&lt;p&gt;Starting from one monolithic &lt;code class=&quot;highlighter-rouge&quot;&gt;ChinaScraper&lt;/code&gt; class, I used Replace Method with Method Object to extract out most of the logic from this class into a &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionScraper&lt;/code&gt; class. Then I went to town using Extract Method to create a bunch of small methods that followed the Single Responsibility Principle (SRP). Having done this, it was clear that my code could benefit from a Replace Type Code with Polymorphism refactoring.&lt;/p&gt;

&lt;p&gt;All told, the shape of my code morphed from its original form – one 170 line class hinging on a 90 line method – to a more modular form where code was sectioned off into five classes and two modules, and methods were used for one purpose only.&lt;/p&gt;

&lt;p&gt;The final step here was to take all of this code out of the &lt;code class=&quot;highlighter-rouge&quot;&gt;db/seeds.rb&lt;/code&gt; file and put it into the &lt;code class=&quot;highlighter-rouge&quot;&gt;app/models&lt;/code&gt; directory. This directory’s file structure now looks like this:&lt;/p&gt;

&lt;div class=&quot;highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;app/
|
|__ models/
    |
    |__ concerns/
    |   |
    |   |__ j_vectorable.rb
    |   |
    |   |__ region_assembler.rb
    |
    |__ autonomous_region_assembler.rb
    |
    |__ china_scraper.rb
    |
    |__ municipality_assembler.rb
    |
    |__ province_assembler.rb
    |
    |__ region.rb
    |
    |__ sar_assembler.rb
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;And the final &lt;code class=&quot;highlighter-rouge&quot;&gt;db/seeds.rb&lt;/code&gt; file is now nice and succinct:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;no&quot;&gt;ChinaScraper&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;run&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;h3 id=&quot;room-for-improvement&quot;&gt;Room for Improvement&lt;/h3&gt;

&lt;p&gt;This was a fun project and I really enjoyed taking the time to refactor my code and make it much more clear, concise, and easy to expand upon going forward.&lt;/p&gt;

&lt;p&gt;There are a few areas in which I think I can improve upon in this and future projects:&lt;/p&gt;

&lt;ul&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Regular Expressions.&lt;/strong&gt; I think I got better at writing regular expressions in this project, but it is possible that I would not have needed the polymorphic refactoring if I had used more accurate regular expressions. Regexps are incredibly powerful, and I want to learn a lot more about them.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Testing.&lt;/strong&gt; You may have noticed that I did not follow one very important step of the refactorings from Martin Fowler’s book: “Test.” I am a bit ashamed to admit that I do not have any test coverage on this app. I am not sure whether/how to test the entire Nokogiri and web scraping aspect of the project. This is something I have to look into more for this specific use case, and in general I need to gain more experience doing test-first development.&lt;/p&gt;
  &lt;/li&gt;
  &lt;li&gt;
    &lt;p&gt;&lt;strong&gt;Working more with maps.&lt;/strong&gt; I am glad that I was able to get the China map up and running, and now I am excited to try working with other third-party libraries to create more interesting data visualizations!&lt;/p&gt;
  &lt;/li&gt;
&lt;/ul&gt;
</description>
        <pubDate>Sat, 13 Sep 2014 21:33:42 +0000</pubDate>
        <link>http://callahan.io/blog/2014/09/13/china-map-project-part-4-introducing-polymorphism</link>
        <guid isPermaLink="true">http://callahan.io/blog/2014/09/13/china-map-project-part-4-introducing-polymorphism</guid>
        
        
      </item>
    
      <item>
        <title>China Map Project - Part 3: Refactoring Using Replace Method with Method Object</title>
        <description>&lt;p&gt;&lt;em&gt;This post is the third in a series about my recent side project, &lt;a href=&quot;http://amapofchina.herokuapp.com&quot;&gt;A Map of China&lt;/a&gt;. Check out the &lt;a href=&quot;http://callahan.io/blog/2014/09/11/china-map-project-part-1-nokogiri/&quot;&gt;first post&lt;/a&gt;, &lt;a href=&quot;http://callahan.io/blog/2014/09/11/china-map-project-part-2-bringing-the-map-to-life-with-jvectormap/&quot;&gt;second post&lt;/a&gt;, and the &lt;a href=&quot;https://github.com/callahanchris/china-map&quot;&gt;project repo&lt;/a&gt; on Github.&lt;/em&gt;&lt;/p&gt;

&lt;h3 id=&quot;refactoring&quot;&gt;Refactoring!&lt;/h3&gt;

&lt;p&gt;I enjoy refactoring. I’ve watched &lt;a href=&quot;https://www.youtube.com/watch?v=DC-pQPq0acs&quot;&gt;a few&lt;/a&gt; &lt;a href=&quot;https://www.youtube.com/watch?v=J4dlF0kcThQ&quot;&gt;great&lt;/a&gt; &lt;a href=&quot;https://www.youtube.com/watch?v=8bZh5LMaSmE&quot;&gt;technical talks&lt;/a&gt; on refactoring and delved further into the topic with two amazing books: &lt;a href=&quot;http://www.poodr.com/&quot;&gt;&lt;em&gt;Practical Object-Oriented Design in Ruby&lt;/em&gt;&lt;/a&gt; by Sandi Metz and &lt;a href=&quot;http://martinfowler.com/books/refactoringRubyEd.html&quot;&gt;&lt;em&gt;Refactoring: Ruby Edition&lt;/em&gt;&lt;/a&gt; by Jay Fields, Shane Harvie, and Martin Fowler (with Kent Beck).&lt;/p&gt;

&lt;p&gt;One main lesson I’ve gleaned from these resources and applying their recommendations to my own code is the importance of having clean, succinct, well-designed code. Code that is easy to read is easy to understand and easy to change when the time comes. I find that pushing my code further towards this goal is both highly challenging and highly rewarding work.&lt;/p&gt;

&lt;p&gt;Recently, I have been reading through &lt;em&gt;Refactoring: Ruby Edition&lt;/em&gt; and trying to implement some of the refactoring patterns it outlines into my own code. With regards to my China map application, one pattern struck me as particularly useful: Replace Method with Method Object. Quoting Martin Fowler:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;p&gt;In this book I emphasize the beauty of small methods. By extracting pieces out of a large method, you make things much more comprehensible.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;The difficulty in decomposing a method lies in local variables. If they are rampant, decomposition can be difficult. Using Replace Temp with Query helps to reduce this burden, but occasionally you may find you cannot break down a method that needs breaking. In this case you reach deep into the tool bag and get out your Method Object.&lt;/p&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;– Refactoring: Ruby Edition, page 128&lt;/p&gt;
&lt;/blockquote&gt;

&lt;p&gt;The mechanics of this refactoring (which was “stolen shamelessly from Kent Beck’s &lt;em&gt;Smalltalk Best Practice Patterns&lt;/em&gt;”) are as follows:&lt;/p&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Create a new class, name it after the method.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Give the new class an attribute for the object that hosted the original method (the source object) and an attribute for each temporary variable and each parameter in the method.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Give the new class a constructor that takes the source object and each parameter.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Give the new class a method named “&lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt;”&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Copy the body of the original method into &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt;. Use the source object instance variable for any invocations of the methods on the original object.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Test.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;ol&gt;
    &lt;li&gt;Replace the old method with one that creates the new object and calls &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt;.&lt;/li&gt;
  &lt;/ol&gt;
&lt;/blockquote&gt;

&lt;blockquote&gt;
  &lt;p&gt;– Refactoring: Ruby Edition, page 129&lt;/p&gt;
&lt;/blockquote&gt;

&lt;h3 id=&quot;seeing-the-opportunity-for-refactoring&quot;&gt;Seeing the Opportunity for Refactoring&lt;/h3&gt;

&lt;p&gt;In my original &lt;code class=&quot;highlighter-rouge&quot;&gt;db/seeds.rb&lt;/code&gt; file, I had one &lt;code class=&quot;highlighter-rouge&quot;&gt;ChinaScraper&lt;/code&gt; class that handled… everything. Even though this was a simple app, that is still a red flag. Before refactoring, the &lt;code class=&quot;highlighter-rouge&quot;&gt;ChinaScraper&lt;/code&gt; class was just shy of 170 lines of code – another big red flag. Within that class, there was one 94 line method (!!!) – &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; – doing the bulk of the work. It scraped each region’s Wikipedia page, then went through and assigned about ten different attributes to the region, then saved the region and its various attributes to the database.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;scrape_all_regions&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nokogiri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;

    &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr td a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/special/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; of &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
      &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;span.category a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;
    &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;

    &lt;span class=&quot;c1&quot;&gt;# ... 80 more lines of code ...&lt;/span&gt;

    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;save&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;As you can begin to see in this snippet, the &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; method contained many conditional statements that essentially checked a region’s &lt;code class=&quot;highlighter-rouge&quot;&gt;territorial_designation&lt;/code&gt;. This type checking was inevitable given that the HTML/CSS content of the individual region pages varied significantly based on their territorial designations – more on this in the next post.&lt;/p&gt;

&lt;p&gt;It was clear that the &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; method had far too many (i.e. more than one) responsibilities and several local variables, so I reached deep into the tool bag for the Replace Method with Method Object refactoring.&lt;/p&gt;

&lt;h3 id=&quot;implementing-replace-method-with-method-object&quot;&gt;Implementing Replace Method with Method Object&lt;/h3&gt;

&lt;p&gt;First, I made a new &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class (a slightly more accurate name than the original method) and assigned attributes for all parameters in the &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; method:&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;class&lt;/span&gt; &lt;span class=&quot;nc&quot;&gt;RegionAssembler&lt;/span&gt;
  &lt;span class=&quot;nb&quot;&gt;attr_reader&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;ss&quot;&gt;:page&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The &lt;code class=&quot;highlighter-rouge&quot;&gt;region&lt;/code&gt; ActiveRecord object and &lt;code class=&quot;highlighter-rouge&quot;&gt;page&lt;/code&gt; Nokogiri object would have to be passed through to a new instance of the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class upon initialization.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;initialize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;vi&quot;&gt;@page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;The local variables from the original &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; method were slightly more complicated, so instead of assigning them to &lt;code class=&quot;highlighter-rouge&quot;&gt;attr_reader&lt;/code&gt;s, I used Extract Method for the three local variables in &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; and placed the extracted methods in the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;area_info&lt;/span&gt;
  &lt;span class=&quot;vi&quot;&gt;@area_info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;t&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/km2/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;monetary_info&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Beijing Chongqing }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@monetary_info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s| /&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Shanghai Tianjin }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@monetary_info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s| |cny|usd|\$/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Guangdong }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@monetary_info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedtoprow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s| |\$/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@monetary_info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}[&lt;/span&gt;&lt;span class=&quot;mi&quot;&gt;1&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;].&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s|\$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@monetary_info&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedtoprow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;gdp_per_cap&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Guangdong Hubei }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@gdp_per_cap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s|\$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Shanghai }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@gdp_per_cap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s|\$|US/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Tianjin }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@gdp_per_cap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s|\)/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;elsif&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@gdp_per_cap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedbottomrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\$/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/\s|\$|\[/&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;vi&quot;&gt;@gdp_per_cap&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;||=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr.mergedrow td&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;select&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;tr&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/cny/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;last&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Next, I moved the remainder of the &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; method from the &lt;code class=&quot;highlighter-rouge&quot;&gt;ChinaScraper&lt;/code&gt; class to the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class and renamed it as &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt; in the &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; class.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;if&lt;/span&gt; &lt;span class=&quot;sx&quot;&gt;%w{ Hong\ Kong Macau }&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;include?&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;name&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;tr td a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;find&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;{&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;a&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;match&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;sr&quot;&gt;/special/i&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt; &lt;span class=&quot;p&quot;&gt;}.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot; of &quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;first&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;else&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;search&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s2&quot;&gt;&quot;span.category a&quot;&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;text&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;territorial_designation&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;split&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;map&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;&amp;amp;&lt;/span&gt;&lt;span class=&quot;ss&quot;&gt;:capitalize&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;join&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;s1&quot;&gt;' '&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;)&lt;/span&gt;
  
  &lt;span class=&quot;c1&quot;&gt;# ... 50 more lines of code ...&lt;/span&gt;

  &lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;save&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Finally, from inside the &lt;code class=&quot;highlighter-rouge&quot;&gt;ChinaScraper&lt;/code&gt; class, I instantiated new &lt;code class=&quot;highlighter-rouge&quot;&gt;RegionAssembler&lt;/code&gt; objects and delegated the heavy lifting to them by sending them a simple message: &lt;code class=&quot;highlighter-rouge&quot;&gt;compute&lt;/code&gt;.&lt;/p&gt;

&lt;div class=&quot;language-ruby highlighter-rouge&quot;&gt;&lt;div class=&quot;highlight&quot;&gt;&lt;pre class=&quot;highlight&quot;&gt;&lt;code&gt;&lt;span class=&quot;k&quot;&gt;def&lt;/span&gt; &lt;span class=&quot;nf&quot;&gt;scrape_all_regions&lt;/span&gt;
  &lt;span class=&quot;no&quot;&gt;Region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;all&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;each&lt;/span&gt; &lt;span class=&quot;k&quot;&gt;do&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;|&lt;/span&gt;
    &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt; &lt;span class=&quot;o&quot;&gt;=&lt;/span&gt; &lt;span class=&quot;no&quot;&gt;Nokogiri&lt;/span&gt;&lt;span class=&quot;o&quot;&gt;::&lt;/span&gt;&lt;span class=&quot;no&quot;&gt;HTML&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;nb&quot;&gt;open&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;url&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;))&lt;/span&gt;
    &lt;span class=&quot;no&quot;&gt;RegionAssembler&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;.&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;new&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;(&lt;/span&gt;&lt;span class=&quot;n&quot;&gt;region&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;,&lt;/span&gt; &lt;span class=&quot;n&quot;&gt;page&lt;/span&gt;&lt;span class=&quot;p&quot;&gt;).&lt;/span&gt;&lt;span class=&quot;nf&quot;&gt;compute&lt;/span&gt;
  &lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;span class=&quot;k&quot;&gt;end&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;

&lt;p&gt;Awesome four line method! The &lt;code class=&quot;highlighter-rouge&quot;&gt;ChinaScraper&lt;/code&gt; class is now a relatively slim 36 lines of code and adheres much more to the Single Responsibility Principle (SRP) than its previous 170 line incarnation.&lt;/p&gt;

&lt;h3 id=&quot;closing-thoughts&quot;&gt;Closing Thoughts&lt;/h3&gt;

&lt;p&gt;This initial refactoring made all subsequent refactorings to the &lt;code class=&quot;highlighter-rouge&quot;&gt;db/seeds.rb&lt;/code&gt; file significantly easier. It seems like a pretty minimal refactoring at this point, but replacing the &lt;code class=&quot;highlighter-rouge&quot;&gt;scrape_all_regions&lt;/code&gt; method with a class was a great first step of breaking the problem up into smaller pieces. This allowed me to think more freely about the problem and began the process of reducing the clutter in my code.&lt;/p&gt;

&lt;p&gt;As I alluded to above, the regional classifications of China that led to a glut of conditional statements were also an open door to a polymorphic refactoring, which is the topic of the &lt;a href=&quot;http://callahan.io/blog/2014/09/13/china-map-project-part-4-introducing-polymorphism/&quot;&gt;next&lt;/a&gt; (and last!) post in this series.&lt;/p&gt;
</description>
        <pubDate>Fri, 12 Sep 2014 19:05:42 +0000</pubDate>
        <link>http://callahan.io/blog/2014/09/12/china-map-project-part-3-refactoring-using-replace-method-with-method-object</link>
        <guid isPermaLink="true">http://callahan.io/blog/2014/09/12/china-map-project-part-3-refactoring-using-replace-method-with-method-object</guid>
        
        
      </item>
    
  </channel>
</rss>
