<?xml version="1.0" encoding="utf-8"?><feed xmlns="http://www.w3.org/2005/Atom" ><generator uri="https://jekyllrb.com/" version="4.4.1">Jekyll</generator><link href="https://unfoundedlabs.com/feed.xml" rel="self" type="application/atom+xml" /><link href="https://unfoundedlabs.com/" rel="alternate" type="text/html" /><updated>2026-09-24T16:33:03+00:00</updated><id>https://unfoundedlabs.com/feed.xml</id><title type="html">Unfounded Labs</title><subtitle>Web Experiments</subtitle><entry><title type="html">Free Parking - New York City</title><link href="https://unfoundedlabs.com/blog/nyc-moto-parking" rel="alternate" type="text/html" title="Free Parking - New York City" /><published>2026-01-05T00:00:00+00:00</published><updated>2026-01-05T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/moto-parking</id><content type="html" xml:base="https://unfoundedlabs.com/blog/nyc-moto-parking"><![CDATA[<h3 id="alternate-side-parking">Alternate Side Parking</h3>

<p>Free Parking in NYC can be found if you’re willing to navigate the world of “Alternate Side Parking” (ASP). A couple times per week, parkers need to accommodate street-sweeping trucks by moving their cars to the “alternate side” of the street. Ask any NYC street-parker about this and they’ll bore you with details of their little weekly routine.</p>

<p>Most of this free parking is in residential neighborhoods, but surprisingly, you can find it just about anywhere. If you know where to look, you’ll find spots in Midtown, SoHo, Chinatown, FiDi, Union Square, Flushing etc.</p>

<p>And when I say you’ll find these spots anywhere - technically true, but the spots you find will be occupied, as free parking is at nearly 100% utilization around the clock, especially in busy and/or commercial areas.</p>

<p>However, if you’re riding a Vespa or motorcycle, you don’t have this problem — you can always find space backed-in between parked cars (this scenario is the actual motivation for this post/app).</p>

<p>On two wheels, you can park anywhere in NYC for free at any time. Given this, I continue to be surprised at the low numbers of Vespas/motorcycles in NYC. Though, car drivers are insane and most people value their lives so perhaps that’s a reason.</p>

<p>Anyways, where are these spots? There isn’t a free parking map provided by the city. The NYC DOT provides <a href="https://nycdotsigns.net">this map</a>, which has some fidgets and widgets that don’t seem to solve our problem.</p>

<p>So let’s make a map: <a href="https://parkgratis.com">parkgratis.com</a></p>

<h3 id="building-the-map">Building the Map</h3>

<p>All the code for this map is <a href="https://github.com/eri-b/moto-parking">available here</a>, and is separated into two areas - <code class="language-plaintext highlighter-rouge">app</code> and <code class="language-plaintext highlighter-rouge">data_processing</code>.</p>

<p><code class="language-plaintext highlighter-rouge">app</code> builds the website and <code class="language-plaintext highlighter-rouge">data_processing</code> does … data processing.</p>

<p>I’ll spare you the details — feed the repo into your favorite LLM if you want to dig in — rather I’ll touch on a few points I think are worth mentioning</p>

<h3 id="data">Data</h3>

<p>NYC Open Data provides this <a href="https://data.cityofnewyork.us/Transportation/Parking-Regulation-Locations-and-Signs/nfid-uabd/about_data">dataset</a>.</p>

<p>This file contains all <em>Parking Regulation Locations and Signs</em> in NYC. There are 440,363 rows, corresponding to 440,363 parking signs.</p>

<p>Here is an abridged sample:</p>

<div class="table">

  <table>
    <thead>
      <tr>
        <th>borough</th>
        <th>on_street</th>
        <th>sign_description</th>
        <th>sign_x_coord</th>
        <th>sign_y_coord</th>
      </tr>
    </thead>
    <tbody>
      <tr>
        <td>Manhattan</td>
        <td>3 AVENUE</td>
        <td>2 HMP SATURDAY 8AM-7PM &lt;-&gt;</td>
        <td>996877</td>
        <td>222815</td>
      </tr>
      <tr>
        <td>Bronx</td>
        <td>EAST 217 STREET</td>
        <td>TRUCK (SYMBOL) TRUCK LOADING ONLY MONDAY-FRIDAY 8AM-6PM –&gt; (SUPERSEDES SP-449CA &amp; SP-70BA)</td>
        <td>1022145</td>
        <td>260647</td>
      </tr>
      <tr>
        <td>Manhattan</td>
        <td>3 AVENUE</td>
        <td>1 HMP COMMERCIAL VEHICLES ONLY MONDAY-FRIDAY 8AM-7PM &lt;-&gt;</td>
        <td>996877</td>
        <td>222815</td>
      </tr>
      <tr>
        <td>Queens</td>
        <td>NORTHERN BOULEVARD</td>
        <td>LOCAL MTA BUS ROUTE PANEL (TEXT TO BE MODIFIED AS REQUESTED)</td>
        <td>1057386</td>
        <td>219889</td>
      </tr>
      <tr>
        <td>Manhattan</td>
        <td>HUDSON STREET</td>
        <td>NO PARKING (SANITATION BROOM SYMBOL) 7:30AM-8AM EXCEPT SUNDAY –&gt; (SUPERSEDES SP-139CA &amp; PS-23BA)</td>
        <td>982560</td>
        <td>207047</td>
      </tr>
    </tbody>
  </table>

</div>

<p>This snippet only shows a handful of columns, but the full set has 25 columns:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>"order_number","record_type","borough","on_street","from_street","to_street","side_of_street","sign_code","sign_description","distance_from_intersection","sign_x_coord","sign_y_coord"
</code></pre></div></div>

<h3 id="alternate-side-parking-asp">Alternate Side Parking (ASP)</h3>

<p>Unfortunately, none of the columns mention anything about “Free Parking”, because the truth is a bit more complicated.</p>

<p>Free parking sometimes exists on streets that have <a href="https://portal.311.nyc.gov/article/?kanumber=KA-01011">ASP</a></p>

<p>Some streets (or sections of streets) can have multiple overlapping signs; so a street with ASP doesn’t guarantee free parking.</p>

<p>Looking at the sample data in the <code class="language-plaintext highlighter-rouge">sign_description</code> column, we can equate ASP with the text “Broom Symbol” (ie street sweeping)</p>

<h3 id="when-is-asp-free">When is ASP free?</h3>

<p>My heuristic, which seems right 95% of the time, is that ASP zones with:</p>

<ul>
  <li>90 minute ranges are free</li>
  <li>Shorter ranges (30 minutes) tend to come with additional restrictions (ie parking meters, special permits, etc).</li>
  <li>Longer ranges (4 hours) are hard to predict. Sometimes free, sometimes not.</li>
  <li>Overnight restrictions are also hard to predict. Sometimes free, sometimes not.</li>
</ul>

<p>I’ve found this approach to be pretty reliable in practice (but suggestions welcome).</p>

<h3 id="data-processing">Data Processing</h3>

<p>We have 440,363 rows that we need to parse, looking for “BROOM SYMBOL” with a 90 minute range.</p>

<p>Regex handles most of the heavy lifting here. You can see the details <a href="https://github.com/eri-b/moto-parking/blob/main/data_processing/csv_parser.rb">here</a>.</p>

<p>For our output file, we don’t need all 25 columns of data - we just mapping these locations eventually, so we just bring along:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>'borough',
'on_street',
'from_street',
'to_street',
'sign_description',
'sign_x_coord_lat',
'sign_y_coord_lon'
</code></pre></div></div>

<h3 id="dupes">Dupes</h3>

<p>On any given city block, there can be multiple signs saying the same thing at different locations on that block. For performance and UI reasons, we only want to display one of these signs per block.</p>

<p>To do this, we must check for duplicates:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># outside loop</span>
<span class="n">seen_keys</span> <span class="o">=</span> <span class="no">Set</span><span class="p">.</span><span class="nf">new</span>

<span class="c1"># inside loop (of 441k rows)</span>
<span class="n">key</span> <span class="o">=</span> <span class="p">[</span>
  <span class="n">borough</span><span class="p">,</span>
  <span class="n">row</span><span class="p">[</span><span class="s1">'on_street'</span><span class="p">].</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">strip</span><span class="p">,</span>
  <span class="n">row</span><span class="p">[</span><span class="s1">'from_street'</span><span class="p">].</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">strip</span><span class="p">,</span>
  <span class="n">row</span><span class="p">[</span><span class="s1">'to_street'</span><span class="p">].</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">strip</span><span class="p">,</span>
  <span class="n">desc</span><span class="p">.</span><span class="nf">to_s</span><span class="p">.</span><span class="nf">strip</span>
<span class="p">]</span>

<span class="k">next</span> <span class="k">if</span> <span class="n">seen_keys</span><span class="p">.</span><span class="nf">include?</span><span class="p">(</span><span class="n">key</span><span class="p">)</span>

<span class="n">seen_keys</span> <span class="o">&lt;&lt;</span> <span class="n">key</span>
</code></pre></div></div>

<p>On any given block, all signs will have the same <code class="language-plaintext highlighter-rouge">on_street</code>, <code class="language-plaintext highlighter-rouge">from_street</code>, <code class="language-plaintext highlighter-rouge">to_street</code>, and <code class="language-plaintext highlighter-rouge">borough</code>. And we need to check the sign description <code class="language-plaintext highlighter-rouge">desc</code> to make sure it’s actually a duplicate.</p>

<p>To do this in Ruby, a <code class="language-plaintext highlighter-rouge">Set</code> datatype is ideal for identifying duplicates, we just fill it like an array, and checking for presence of data is very fast.</p>

<h3 id="coordinates">Coordinates</h3>

<p>Eventually we’ll plot these signs on a map, and if we look back to the sample data, we’ll see that we have <code class="language-plaintext highlighter-rouge">sign_x_coord</code> and <code class="language-plaintext highlighter-rouge">sign_y_coord</code>.</p>

<p>Only thing is they don’t appear to be latitude and longitude. Rather they are EPSG:2263 coordinates (<a href="https://en.wikipedia.org/wiki/EPSG_Geodetic_Parameter_Dataset">EPSG</a> is the system, and <a href="https://spatialreference.org/ref/epsg/2263/">2263</a> corresponds to the NYC region).</p>

<p>EPSG is an alternate system meant for hyper-local location targeting - which in this case - signs on a city block - seems to be a valid use case.</p>

<p>We need to convert these coordinates to lat/long to feed into Google maps - <a href="https://github.com/eri-b/moto-parking/blob/main/data_processing/coordinate_converter.rb">here’s our converter</a>.</p>

<h3 id="app">App</h3>

<p>The processed data is exported to a CSV file that we load into our frontend. It’s all fairly straightforward HTML, Javascript, Google Maps Apis, with most of the logic living <a href="https://github.com/eri-b/moto-parking/blob/main/app/map.js">here</a>.</p>

<h3 id="frontend-performance">Frontend Performance</h3>

<p>We started with 440,363 rows in our original dataset, and after filtering for 90 minute ASP and removing dupes, we have 57,587 rows in our   <a href="https://github.com/eri-b/moto-parking/blob/main/app/data/source.csv">CSV</a>.</p>

<p>If we try to add 57,587 markers onto a Google Map, our browser will explode.</p>

<p>Instead, we have a couple of performance-related tricks.</p>

<ol>
  <li>Segment all the markers by borough, and default to showing Manhattan markers. You can still enable all 5 boroughs using the checkboxes, but at least on initial load, we reduce loading by 89% (only 11% of signs are in Manhattan).</li>
  <li>Use heat maps when zoomed out. We determined a zoom threshold  where showing individual location markers would render quickly (<code class="language-plaintext highlighter-rouge">const MARKER_ZOOM_THRESHOLD = 16;</code>), and when zoomed out farther than that, we’ll display a heat map of the markers, rather than the markers themselves. Heat maps are performant and useful for large chunks of location data. It’s still important to have the individual markers at an appropriate zoom level, so that we can see information regarding that sign, and even pop into a street view if need be.</li>
</ol>

<h3 id="the-end">The end</h3>

<p>Ride safe and free park.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Alternate Side Parking]]></summary></entry><entry><title type="html">A New Enumerable Method</title><link href="https://unfoundedlabs.com/blog/all_but" rel="alternate" type="text/html" title="A New Enumerable Method" /><published>2023-05-05T00:00:00+00:00</published><updated>2023-05-05T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/all-but</id><content type="html" xml:base="https://unfoundedlabs.com/blog/all_but"><![CDATA[<h3 id="open-classes">Open Classes</h3>

<p>Ruby allows anyone … yes you … to customize things to your own liking. Update existing methods, add new ones, etc.</p>

<p>One way to accomplish this is through this concept of <em>Open Classes</em>. In our own code, we can open any class that has already been defined (either from the <em>Core Library</em> or our own code), and just put stuff in.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">String</span>
  <span class="k">def</span> <span class="nf">disguise</span>
	  <span class="nb">self</span><span class="p">[</span><span class="mi">1</span><span class="o">...-</span><span class="mi">1</span><span class="p">]</span> <span class="o">=</span> <span class="s2">"*"</span> <span class="o">*</span> <span class="p">(</span><span class="nb">self</span><span class="p">.</span><span class="nf">size</span> <span class="o">-</span> <span class="mi">2</span><span class="p">)</span>
	  <span class="nb">self</span>
  <span class="k">end</span>
<span class="k">end</span>

<span class="s2">"john smith"</span><span class="p">.</span><span class="nf">disguise</span>
<span class="o">=&gt;</span> <span class="s2">"j********h"</span>

<span class="s2">"43829"</span><span class="p">.</span><span class="nf">disguise</span>
<span class="o">=&gt;</span> <span class="s2">"4***9"</span>
</code></pre></div></div>

<p>This <code class="language-plaintext highlighter-rouge">#disguise</code> method hides all characters but the first and the last.</p>

<p>This method is fun, but isn’t really the focus - the point is we can add methods to all classes, even those from the Ruby core library (class <code class="language-plaintext highlighter-rouge">String</code> in this case).</p>

<h3 id="all">#All?</h3>

<p>If you’ve used Ruby, you’ve probably used <code class="language-plaintext highlighter-rouge">#all?</code>.</p>

<p><code class="language-plaintext highlighter-rouge">#all?</code> is defined in the <code class="language-plaintext highlighter-rouge">Enumberable</code> module, which is included in a few Ruby classes, and for <code class="language-plaintext highlighter-rouge">Array</code>, we can use it like:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">].</span><span class="nf">all?</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:positive?</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="kp">true</span>

<span class="p">[</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">].</span><span class="nf">all?</span> <span class="k">do</span> <span class="o">|</span><span class="n">number</span><span class="o">|</span>
	<span class="n">number</span> <span class="o">&gt;</span> <span class="mi">2</span>
<span class="k">end</span>
<span class="o">=&gt;</span> <span class="kp">false</span>

</code></pre></div></div>

<p>But what if we want to know whether <em>most</em> of the elements of an array satisfy a certain condition, not <em>all</em>.</p>

<p>Let’s say we wanted to check if all but one of the values of an array of numbers are positive. We could do something like:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">count</span><span class="p">(</span><span class="o">&amp;</span><span class="ss">:positive?</span><span class="p">)</span> <span class="o">&gt;=</span> <span class="p">(</span><span class="n">arr</span><span class="p">.</span><span class="nf">size</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="kp">true</span>
</code></pre></div></div>

<p>This is okay, but if we need this behavior often, let’s create a method to handle it.</p>

<h3 id="all_but">#all_but?</h3>

<p>Ideally, we’ll be able to use this new method like:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">val</span><span class="o">|</span>
	<span class="n">val</span><span class="p">.</span><span class="nf">positive?</span>
<span class="k">end</span>
<span class="o">=&gt;</span> <span class="kp">true</span>
</code></pre></div></div>

<p>or with shorthand notation:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="ss">:positive?</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="kp">true</span>
</code></pre></div></div>

<h3 id="open-the-class">Open the Class</h3>

<p>First step is to open the <code class="language-plaintext highlighter-rouge">Array</code> class.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
  <span class="k">def</span> <span class="nf">all_but?</span><span class="p">(</span><span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
	  <span class="nb">puts</span> <span class="nb">self</span>
	  <span class="nb">puts</span> <span class="n">number</span>
	<span class="k">end</span>
<span class="k">end</span>

<span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">].</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">,</span><span class="mi">4</span><span class="p">]</span>
<span class="o">=&gt;</span> <span class="mi">2</span>


<span class="p">[</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">].</span><span class="nf">all_but?</span>
<span class="o">=&gt;</span> <span class="p">[</span><span class="mi">8</span><span class="p">,</span><span class="mi">9</span><span class="p">,</span><span class="mi">10</span><span class="p">]</span>
<span class="o">=&gt;</span> <span class="mi">0</span> <span class="c1"># default argument</span>
</code></pre></div></div>

<p>Simple as that - now we have <code class="language-plaintext highlighter-rouge">#all_but?</code> available for our arrays.</p>

<h3 id="iterate">Iterate</h3>

<p>Now that we see that we have access to <code class="language-plaintext highlighter-rouge">self</code> inside our method, we iterate through it, to implement some sort of count.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
  <span class="k">def</span> <span class="nf">all_but?</span><span class="p">(</span><span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
	  <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
	  <span class="c1"># self is implied (ie self.each)</span>
	  <span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="p">[</span><span class="o">..</span><span class="n">some</span> <span class="n">logic</span><span class="o">..</span><span class="p">]</span> <span class="p">}</span>
	  <span class="n">count</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<h3 id="yield">Yield</h3>

<p>We’ll use <code class="language-plaintext highlighter-rouge">yield</code> to grab any code that was passed into the block.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">val</span><span class="o">|</span>
	<span class="n">val</span><span class="p">.</span><span class="nf">positive?</span>
<span class="k">end</span>
</code></pre></div></div>

<p>In this example, we’ll access <code class="language-plaintext highlighter-rouge">val.positive?</code> via the <code class="language-plaintext highlighter-rouge">yield</code> method.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
  <span class="k">def</span> <span class="nf">all_but?</span><span class="p">(</span><span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
    <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
	  <span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="k">yield</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="p">}</span>
    <span class="n">count</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>We’re testing <code class="language-plaintext highlighter-rouge">each</code> element of our array against the code we passed in the block.</p>

<p>Temporarily, we’re just returning the count, so with this implementation, we should expect to return <code class="language-plaintext highlighter-rouge">4</code>:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">val</span><span class="o">|</span>
	<span class="n">val</span><span class="p">.</span><span class="nf">positive?</span>
<span class="k">end</span>
<span class="o">=&gt;</span> <span class="mi">4</span>
</code></pre></div></div>

<h3 id="semi-final-touches">Semi-final Touches</h3>

<p>Instead of returning the count of elements that pass our test, let’s actually check the computed count against our target count.</p>

<p>This method is meant to check if <em>all but</em> a certain number of elements pass the test. So essentially, we’re excepting some number of elements from our test.</p>

<p>And we pass this exception count as an argument to <code class="language-plaintext highlighter-rouge">#all_but</code>.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
	<span class="k">def</span> <span class="nf">all_but?</span><span class="p">(</span><span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
		<span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
		<span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="k">yield</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="p">}</span>
		<span class="n">count</span> <span class="o">&gt;=</span> <span class="n">length</span> <span class="o">-</span> <span class="n">number</span>
	<span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>That’s it!*</p>

<p>Let’s run a couple of tests:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="o">-</span><span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">val</span><span class="o">|</span>
	<span class="n">val</span><span class="p">.</span><span class="nf">positive?</span>
<span class="k">end</span>
<span class="o">=&gt;</span> <span class="kp">false</span>

<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span> <span class="k">do</span> <span class="o">|</span><span class="n">val</span><span class="o">|</span>
	<span class="n">val</span><span class="p">.</span><span class="nf">positive?</span>
<span class="k">end</span>
<span class="o">=&gt;</span> <span class="kp">true</span>
</code></pre></div></div>

<p>* Now let’s consider an edge case.</p>

<h3 id="blockless">Blockless</h3>

<p>What if someone doesn’t pass in a block?</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
</code></pre></div></div>

<p>Currently, this will raise the exception <code class="language-plaintext highlighter-rouge">LocalJumpError: no block given (yield)</code>. We can’t call <code class="language-plaintext highlighter-rouge">yield</code> without a block.</p>

<p>Fortunately, Ruby gives us a handy <code class="language-plaintext highlighter-rouge">block_given?</code> method.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
  <span class="k">def</span> <span class="nf">all_but?</span><span class="p">(</span><span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
    <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">if</span> <span class="o">!</span><span class="nb">block_given?</span>
			<span class="c1"># do something?</span>
    <span class="k">else</span>
      <span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="k">yield</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="p">}</span>
    <span class="k">end</span>
    <span class="n">count</span> <span class="o">&gt;=</span> <span class="n">length</span> <span class="o">-</span> <span class="n">number</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<h3 id="truthiness">Truthiness</h3>

<p>The good news is that virtually all Ruby objects are <em>truthy</em> or <em>falsey</em>; meaning, they resolve to <code class="language-plaintext highlighter-rouge">true</code> or <code class="language-plaintext highlighter-rouge">false</code>.</p>

<p>All objects in Ruby except for <code class="language-plaintext highlighter-rouge">nil</code> and <code class="language-plaintext highlighter-rouge">false</code> evaluate to true <code class="language-plaintext highlighter-rouge">true</code>. One way to test this is using the <em>double bang</em>.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="o">!!</span><span class="mi">3</span>
<span class="o">=&gt;</span> <span class="kp">true</span>

<span class="o">!!</span><span class="s2">"string"</span>
<span class="o">=&gt;</span> <span class="kp">true</span>

<span class="o">!!</span><span class="s2">""</span>
<span class="o">=&gt;</span> <span class="kp">true</span>

<span class="o">!!</span><span class="kp">true</span>
<span class="o">=&gt;</span> <span class="kp">true</span>

<span class="o">!!</span><span class="kp">nil</span>
<span class="o">=&gt;</span> <span class="kp">false</span>

<span class="o">!!</span><span class="kp">false</span>
<span class="o">=&gt;</span> <span class="kp">false</span>
</code></pre></div></div>

<p>The <em>double bang</em> works by negating the object twice.</p>

<p><code class="language-plaintext highlighter-rouge">!(!3)</code> becomes <code class="language-plaintext highlighter-rouge">!(false)</code> which becomes true.</p>

<p>So we don’t actually require code coming in from the block to test each item in the array, since each object can be treated as its own test.</p>

<p>For example, <code class="language-plaintext highlighter-rouge">#all?</code> works in this same way:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="kp">true</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"hello"</span><span class="p">].</span><span class="nf">all?</span>
<span class="o">=&gt;</span> <span class="kp">true</span>

<span class="p">[</span><span class="kp">true</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"hello"</span><span class="p">,</span> <span class="kp">nil</span><span class="p">].</span><span class="nf">all?</span>
<span class="o">=&gt;</span> <span class="kp">false</span>
</code></pre></div></div>

<h3 id="edge-case-continued">Edge Case Continued</h3>

<p>Let’s replace <code class="language-plaintext highlighter-rouge"># do something</code> :</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
  <span class="k">def</span> <span class="nf">all_but?</span><span class="p">(</span><span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
    <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">if</span> <span class="o">!</span><span class="nb">block_given?</span>
      <span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">item</span> <span class="p">}</span>
    <span class="k">else</span>
      <span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="k">yield</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="p">}</span>
    <span class="k">end</span>
    <span class="n">count</span> <span class="o">&gt;=</span> <span class="n">length</span> <span class="o">-</span> <span class="n">number</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>

<p>Since each item of the array can evaluate to <code class="language-plaintext highlighter-rouge">true</code> or <code class="language-plaintext highlighter-rouge">false</code>, we can simply ask <code class="language-plaintext highlighter-rouge">if [item]</code>.</p>

<p>In action:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[</span><span class="kp">false</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"hello"</span><span class="p">].</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="kp">true</span>

<span class="p">[</span><span class="kp">true</span><span class="p">,</span> <span class="mi">2</span><span class="p">,</span> <span class="s2">"hello"</span><span class="p">,</span> <span class="kp">false</span><span class="p">,</span> <span class="kp">nil</span><span class="p">].</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="kp">false</span>
</code></pre></div></div>

<h3 id="shorthand-notation">Shorthand Notation</h3>

<p>We’re basically done at this point, but just wanted to confirm that our method works with shorthand notation; that is; when the block is passed as the last argument of the method.</p>

<p>To accomplish this, we need to preface our block code with an <code class="language-plaintext highlighter-rouge">&amp;</code>.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">arr</span> <span class="o">=</span> <span class="p">[</span><span class="mi">2</span><span class="p">,</span> <span class="mi">4</span><span class="p">,</span> <span class="mi">1</span><span class="p">,</span> <span class="o">-</span><span class="mi">3</span><span class="p">,</span> <span class="mi">9</span><span class="p">]</span>
<span class="n">arr</span><span class="p">.</span><span class="nf">all_but?</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="o">&amp;</span><span class="ss">:positive?</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="kp">true</span>
</code></pre></div></div>

<h3 id="the-end">The end</h3>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Array</span>
  <span class="k">def</span> <span class="nf">all_but?</span><span class="p">(</span><span class="n">number</span> <span class="o">=</span> <span class="mi">0</span><span class="p">)</span>
    <span class="n">count</span> <span class="o">=</span> <span class="mi">0</span>
    <span class="k">if</span> <span class="o">!</span><span class="nb">block_given?</span>
      <span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="n">item</span> <span class="p">}</span>
    <span class="k">else</span>
      <span class="n">each</span> <span class="p">{</span> <span class="o">|</span><span class="n">item</span><span class="o">|</span> <span class="n">count</span> <span class="o">+=</span> <span class="mi">1</span> <span class="k">if</span> <span class="k">yield</span><span class="p">(</span><span class="n">item</span><span class="p">)</span> <span class="p">}</span>
    <span class="k">end</span>
    <span class="n">count</span> <span class="o">&gt;=</span> <span class="n">length</span> <span class="o">-</span> <span class="n">number</span>
  <span class="k">end</span>
<span class="k">end</span>
</code></pre></div></div>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Open Classes]]></summary></entry><entry><title type="html">Treating Operators as Methods</title><link href="https://unfoundedlabs.com/blog/operator-methods" rel="alternate" type="text/html" title="Treating Operators as Methods" /><published>2023-03-03T00:00:00+00:00</published><updated>2023-03-03T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/operators</id><content type="html" xml:base="https://unfoundedlabs.com/blog/operator-methods"><![CDATA[<h3 id="oop">OOP</h3>

<p>Ruby is an Object Oriented Programming language, so most everything is an object (i.e. an instance of some class), and we can call methods on our objects.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">3</span><span class="p">.</span><span class="nf">class</span>
<span class="o">=&gt;</span> <span class="no">Integer</span>

<span class="s2">"string"</span><span class="p">.</span><span class="nf">length</span>
<span class="o">=&gt;</span> <span class="mi">6</span>

<span class="p">[</span><span class="mi">1</span><span class="p">,</span><span class="mi">2</span><span class="p">,</span><span class="mi">3</span><span class="p">].</span><span class="nf">include?</span> <span class="mi">1</span>
<span class="o">=&gt;</span> <span class="kp">true</span>
</code></pre></div></div>

<h3 id="operators">Operators</h3>

<p>In Ruby, there are a couple dozen operators: <code class="language-plaintext highlighter-rouge">+</code>, <code class="language-plaintext highlighter-rouge">-</code>, <code class="language-plaintext highlighter-rouge">*</code>, <code class="language-plaintext highlighter-rouge">/</code>, <code class="language-plaintext highlighter-rouge">%</code>, <code class="language-plaintext highlighter-rouge">**</code>, <code class="language-plaintext highlighter-rouge">=</code>, <code class="language-plaintext highlighter-rouge">&lt;</code>, etc.</p>

<p>Some rocket science:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2</span> <span class="o">+</span> <span class="mi">2</span>
<span class="o">=&gt;</span> <span class="mi">4</span>
</code></pre></div></div>

<h3 id="operators-and-oop">Operators and OOP?</h3>

<p>These operators … don’t really look like methods being called on objects?</p>

<p>Well, turns out <code class="language-plaintext highlighter-rouge">2 + 2</code> is a shorthand version of <code class="language-plaintext highlighter-rouge">2.+(2)</code> where <code class="language-plaintext highlighter-rouge">+</code> is just a method of the Integer class.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">2</span><span class="p">.</span><span class="nf">+</span><span class="p">(</span><span class="mi">2</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="mi">4</span>

<span class="mi">2</span><span class="p">.</span><span class="nf">+</span> <span class="mi">2</span> <span class="c1"># parens optional</span>
<span class="o">=&gt;</span> <span class="mi">4</span>
</code></pre></div></div>

<h3 id="native-classes">Native classes</h3>

<p>Not all operators are available everywhere - each class specifies which operators to support.</p>

<p>For <code class="language-plaintext highlighter-rouge">Integer</code>, there are many operators, as we tend to like to operate on integers.</p>

<p>A quick glance via <code class="language-plaintext highlighter-rouge">Integer.instance_methods.sort</code>:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="p">[:</span><span class="o">!</span><span class="p">,</span> <span class="p">:</span><span class="o">!=</span><span class="p">,</span> <span class="p">:</span><span class="o">!~</span><span class="p">,</span> <span class="ss">:%</span><span class="p">,</span> <span class="ss">:&amp;</span><span class="p">,</span> <span class="p">:</span><span class="o">*</span><span class="p">,</span> <span class="ss">:**</span><span class="p">,</span> <span class="p">:</span><span class="o">+</span><span class="p">,</span> <span class="p">:</span><span class="o">-</span><span class="p">,</span> <span class="ss">:/</span><span class="p">,</span> <span class="ss">:&lt;</span><span class="p">,</span> <span class="ss">:&lt;&lt;</span><span class="p">,</span> <span class="ss">:&lt;=</span><span class="p">,</span> <span class="ss">:&lt;=&gt;</span><span class="p">,</span> <span class="ss">:==</span><span class="p">,</span> <span class="ss">:===</span><span class="p">,</span> <span class="p">:</span><span class="o">=~</span><span class="p">,</span> <span class="p">:</span><span class="o">&gt;</span><span class="p">,</span> <span class="p">:</span><span class="o">&gt;=</span><span class="p">,</span> <span class="ss">:&gt;&gt;</span><span class="p">,</span> <span class="ss">:[]</span><span class="p">,</span> <span class="ss">:^</span><span class="p">,</span> <span class="o">...</span><span class="p">]</span>
</code></pre></div></div>

<p>There are fewer available for a class like <code class="language-plaintext highlighter-rouge">String</code>; and this makes intuitive sense, as it isn’t clear what a <code class="language-plaintext highlighter-rouge">-</code> would do for an instance of the <code class="language-plaintext highlighter-rouge">String</code> class.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="no">String</span><span class="p">.</span><span class="nf">instance_methods</span><span class="p">.</span><span class="nf">sort</span>

<span class="o">=&gt;</span> <span class="p">[:</span><span class="o">!</span><span class="p">,</span> <span class="p">:</span><span class="o">!=</span><span class="p">,</span> <span class="p">:</span><span class="o">!~</span><span class="p">,</span> <span class="ss">:%</span><span class="p">,</span> <span class="p">:</span><span class="o">*</span><span class="p">,</span> <span class="ss">:&lt;</span><span class="p">,</span> <span class="ss">:&lt;&lt;</span><span class="p">,</span> <span class="ss">:&lt;=</span><span class="p">,</span> <span class="ss">:&lt;=&gt;</span><span class="p">,</span> <span class="ss">:==</span><span class="p">,</span> <span class="ss">:===</span><span class="p">,</span> <span class="p">:</span><span class="o">=~</span><span class="p">,</span> <span class="p">:</span><span class="o">&gt;</span><span class="p">,</span> <span class="p">:</span><span class="o">&gt;=</span><span class="p">,</span> <span class="o">...</span><span class="p">]</span>

</code></pre></div></div>

<p>But one common use of <code class="language-plaintext highlighter-rouge">+</code> for strings is concatenation:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="s2">"my string"</span> <span class="o">+</span> <span class="s2">" has been concatenated"</span>
<span class="o">=&gt;</span> <span class="s2">"my string has been concatenated"</span>
</code></pre></div></div>

<h3 id="custom-classes">Custom Classes</h3>

<p>We can define operators on our own custom classes if we’d like.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Cat</span>
	<span class="nb">attr_reader</span> <span class="ss">:lives_remaining</span>

	<span class="k">def</span> <span class="nf">initialize</span>
		<span class="vi">@lives_remaining</span> <span class="o">=</span> <span class="mi">9</span>
	<span class="k">end</span>

	<span class="k">def</span> <span class="nf">-</span><span class="p">(</span><span class="n">lives</span><span class="p">)</span>
		<span class="vi">@lives_remaining</span> <span class="o">-=</span> <span class="n">lives</span>
	<span class="k">end</span>
<span class="k">end</span>

<span class="n">cat</span> <span class="o">=</span> <span class="no">Cat</span><span class="p">.</span><span class="nf">new</span>
<span class="n">cat</span><span class="p">.</span><span class="nf">lives_remaining</span>
<span class="o">=&gt;</span> <span class="mi">9</span>
<span class="n">cat</span> <span class="o">-</span> <span class="mi">3</span>
<span class="n">cat</span><span class="p">.</span><span class="nf">lives_remaining</span>
<span class="o">=&gt;</span> <span class="mi">6</span>
</code></pre></div></div>

<h3 id="why-does-this-matter">Why does this matter?</h3>

<p>Since operators are just methods (usually displayed in shorthand), we can do method-y things!</p>

<p>One example is the safe navigation operator <code class="language-plaintext highlighter-rouge">&amp;</code>.</p>

<p>Sometimes, if we’re not sure whether an object is <code class="language-plaintext highlighter-rouge">nil</code>, we can chain <code class="language-plaintext highlighter-rouge">&amp;</code> before the method call, so we don’t get an <code class="language-plaintext highlighter-rouge">undefined method for nil:NilClass</code>.</p>

<p>It’s quite common to see stuff like <code class="language-plaintext highlighter-rouge">my_object&amp;.my_method</code>.</p>

<h3 id="using-the-safe-navigator-for-operators">Using the Safe Navigator for Operators</h3>

<p>Let’s say we have a method that calculates the tax on a transaction.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">tax</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span>
	<span class="n">amount</span> <span class="o">*</span> <span class="mf">0.07</span>
<span class="k">end</span>

<span class="n">tax</span> <span class="mi">100</span>
<span class="o">=&gt;</span> <span class="mi">7</span>
</code></pre></div></div>

<p>But perhaps in practice, we don’t know the values that will find their way into this method. Occasionally, the argument could be <code class="language-plaintext highlighter-rouge">nil</code>.</p>

<p>Currently, our app would blow up:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">amount</span> <span class="o">=</span> <span class="kp">nil</span>
<span class="n">tax</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span>
<span class="sb">`undefined method `</span><span class="o">*</span><span class="err">'</span> <span class="k">for</span> <span class="kp">nil</span><span class="ss">:NilClass</span> <span class="p">(</span><span class="no">NoMethodError</span><span class="p">)</span><span class="sb">`
</span></code></pre></div></div>

<p>Let’s redefine our method using the safe navigation operator:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">tax</span><span class="p">(</span><span class="n">amount</span><span class="p">)</span>
	<span class="n">amount</span><span class="o">&amp;</span><span class="p">.</span><span class="nf">*</span> <span class="mf">0.07</span>
<span class="k">end</span>

<span class="n">tax</span><span class="p">(</span><span class="kp">nil</span><span class="p">)</span>
<span class="o">=&gt;</span> <span class="kp">nil</span>
</code></pre></div></div>

<p>Another possible solution would be to protect areas of code with guard clauses (ie <code class="language-plaintext highlighter-rouge">return if amount.nil?</code>), but the save navigation operator is nice and tidy, and in some circumstances, might be enough.</p>

<p>That’s all.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[OOP]]></summary></entry><entry><title type="html">Luring Spam Bots into a Honeypot</title><link href="https://unfoundedlabs.com/blog/honeypot" rel="alternate" type="text/html" title="Luring Spam Bots into a Honeypot" /><published>2021-07-01T00:00:00+00:00</published><updated>2021-07-01T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/honeypot</id><content type="html" xml:base="https://unfoundedlabs.com/blog/honeypot"><![CDATA[<h3 id="a-custom-solution-using-rails">A custom solution using Rails</h3>

<p>I made a <a href="https://bouncerip.com">website</a> with user accounts, and put it online. Within a couple of days, the bots managed to track it down.</p>

<p>Every 20 minutes or so, an account would be created with a username that looked like <em>mBxzKObvCDiWhgt</em></p>

<p>Bots that create accounts systemically, every 20 minutes, forever, is not good.</p>

<ol>
  <li>They take up server resources and slow down the site for actual humans.</li>
  <li>They also mess up the product. When actual humans try to find other users, they shouldn’t have to wade through a mess of bot accounts.</li>
</ol>

<h3 id="how-they-get-in">How they get in</h3>

<p>They arrive on the <em>Sign Up</em> page, and submit a form. The form was designed to be simple and quick, so there’s minimal friction for new (human) users.</p>

<p>The flip side is that the form is so simple that robots can figure it out. Only the regular stuff is required: username, password, email. Nothing fancy in the way of Captchas.</p>

<h3 id="captchas">Captchas</h3>

<p>Captcha is short for <em>Completely Automated Public Turing test to tell Computers and Humans Apart</em>. I just double-checked that was correct, because it seems it should probably be <em>CAPTTTTCAHA</em>.</p>

<p>Anyways, what’s important is what they do — attempt to distinguish between humans and robots. Unfortunately this is usually to the detriment of the user experience.</p>

<p>Before you can post something, you have to find a bridge in 9 small, grainy images.</p>

<p><img src="/assets/images/blog/bridge.png" alt="" /></p>

<p>Apparently robots aren’t good at this practice, and turns out, neither am I.</p>

<h3 id="honeypots">Honeypots</h3>

<p>Honeypots are like reverse Captchas. Instead of asking humans to do the work to prove they aren’t a robot, let’s trick the robot into doing some work.</p>

<p>Once we see a user with his (mechanical) finger in the honeypot, we can safely assume we’ve identified a robot.</p>

<p>This works by adding an additional field to a form, that’s hidden from view. A human won’t see this field, and won’t fill it out. A robot doesn’t have eyes, so they just fill out everything in a form that seems important.</p>

<p>When our application receives the form, if the <em>honeypot</em> field is filled out, we have ourselves a robot. In our case, let’s throw out this data, and <em>not</em> sign up <em>mBxzKObvCDiWhgt</em>.</p>

<h3 id="implementation-using-rails">Implementation using Rails</h3>

<p>There’s a Rails gem called <a href="https://github.com/markets/invisible_captcha">invisible_captcha</a> that does exactly what we just described, but it didn’t seem to work for the bots we are dealing with at <a href="https://bouncerip.com">Bounce</a>, so let’s build a custom honeypot.</p>

<h3 id="sign-up-form">Sign Up Form</h3>

<p>Inside our form, we include this:</p>

<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;div</span> <span class="na">class=</span><span class="s">"hp"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;input</span> <span class="na">type=</span><span class="s">"checkbox"</span> <span class="na">value=</span><span class="s">"1"</span> <span class="na">name=</span><span class="s">"hp"</span> <span class="na">id=</span><span class="s">"hp"</span> <span class="na">autocomplete=</span><span class="s">"off"</span> <span class="na">tabindex=</span><span class="s">"-1"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;label</span> <span class="na">for=</span><span class="s">"hp"</span><span class="nt">&gt;</span>Huemans should NOT clik this.<span class="nt">&lt;/label&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<p>And the <code class="language-plaintext highlighter-rouge">.hp</code> class has these attributes:</p>

<div class="language-css highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nc">.hp</span><span class="p">{</span>
  <span class="nl">display</span><span class="p">:</span><span class="nb">none</span><span class="p">;</span>
  <span class="nl">position</span><span class="p">:</span><span class="nb">absolute</span><span class="p">;</span>
  <span class="nl">overflow</span><span class="p">:</span><span class="nb">hidden</span><span class="p">;</span>
  <span class="nl">width</span><span class="p">:</span><span class="m">1px</span><span class="p">;</span>
  <span class="nl">height</span><span class="p">:</span><span class="m">1px</span><span class="p">;</span>
  <span class="nl">opacity</span><span class="p">:</span><span class="m">0</span><span class="p">;</span>
<span class="p">}</span>
</code></pre></div></div>

<p>It’s probably clear from this <code class="language-plaintext highlighter-rouge">CSS</code> that this checkbox is hidden many times over.</p>

<p>For the checkbox itself, we set <code class="language-plaintext highlighter-rouge">autocomplete="off"</code> so your browser doesn’t get involved with any sort of autocompletion.</p>

<p>We have <code class="language-plaintext highlighter-rouge">tabindex="-1"</code> which means that you can’t <code class="language-plaintext highlighter-rouge">tab</code> your way into this field.</p>

<p>We also have an invisible label for this invisible checkbox that says <em>“Huemans should NOT clik this.”</em>. We want this label in the rare chance that the checkbox is visible — maybe a user doesn’t load CSS or they have some weird browser add-on that displays all form fields. Or, if the user is using a screenreader — the label will indicate what’s going on.</p>

<p>So why do we spell it weird? This isn’t an exact science, but there’s a chance that bots have been programmed to actually look out for <code class="language-plaintext highlighter-rouge">honeypots</code>, so we don’t want our warning message to be easily parsed by a robot.</p>

<h3 id="registrations-controller">Registrations Controller</h3>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">class</span> <span class="nc">Users::RegistrationsController</span> <span class="o">&lt;</span> <span class="no">Devise</span><span class="o">::</span><span class="no">RegistrationsController</span>

  <span class="n">before_action</span> <span class="ss">:find_bot</span><span class="p">,</span> <span class="ss">only: :create</span>

  <span class="kp">private</span>

  <span class="k">def</span> <span class="nf">find_bot</span>
    <span class="k">return</span> <span class="k">unless</span> <span class="n">params</span><span class="p">[</span><span class="ss">:hp</span><span class="p">]</span> <span class="o">==</span> <span class="s1">'1'</span>
    <span class="n">head</span> <span class="ss">:ok</span>
  <span class="k">end</span>
<span class="k">end</span>

</code></pre></div></div>

<p>We add a <code class="language-plaintext highlighter-rouge">before_action</code> to the <code class="language-plaintext highlighter-rouge">create</code> action of our <code class="language-plaintext highlighter-rouge">RegistrationsController</code> that checks to see if the checkbox from our form was checked.</p>

<p>The checkbox had a value set of <code class="language-plaintext highlighter-rouge">1</code>; so when checked, we can can expect our <code class="language-plaintext highlighter-rouge">params[:hp]</code> to equal <code class="language-plaintext highlighter-rouge">1</code>.</p>

<p>In our <code class="language-plaintext highlighter-rouge">find_bot</code> method, when the checkbox is checked (<code class="language-plaintext highlighter-rouge">params[:hp]==1</code>), we return <code class="language-plaintext highlighter-rouge">head :ok</code>.</p>

<p>This will halt the request cycle, meaning that the actual <code class="language-plaintext highlighter-rouge">create</code> action never runs. Additionally, by returning <code class="language-plaintext highlighter-rouge">head :ok</code>, we’re returning the status code of 200 to the client, which the robot will interpret as a success.</p>

<h3 id="conclusion">Conclusion</h3>

<p>This custom honeypot seems to work ok for now. We’ve routed our robots into a false sense of success, without cluttering our database with fake accounts. If they become sentient enough to evade this honeypot, I’ll update this post.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[A custom solution using Rails]]></summary></entry><entry><title type="html">Stripe Connect and Ruby’s Tap</title><link href="https://unfoundedlabs.com/blog/stripe-tap" rel="alternate" type="text/html" title="Stripe Connect and Ruby’s Tap" /><published>2021-06-07T00:00:00+00:00</published><updated>2021-06-07T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/stripe-ruby-tap</id><content type="html" xml:base="https://unfoundedlabs.com/blog/stripe-tap"><![CDATA[<h3 id="location-quirks-and-dry-code">Location Quirks and DRY Code</h3>

<p><a href="https://bouncerip.com">Bounce</a> is a platform where people pay to chat with other people. Everything happens in real-time, and is billed on a per-minute basis.</p>

<p>Seems fairly straightforward. We’ll create a <em>Payment Intent</em> (which is Stripe’s newer way of saying <em>charge</em>) after each conversation takes place.</p>

<p>Using <strong>Stripe Connect</strong>, we can even specify <code class="language-plaintext highlighter-rouge">transfer_data</code> — this allows us to transfer money directly from <em>student</em> to <em>teacher</em>.</p>

<h3 id="first-complication">First Complication</h3>

<p>Bounce’s network is global. A teacher in Mexico can help a student in Japan. Luckily, Stripe handles most of the heavy-lifting here.</p>

<p>However, Stripe Connect transactions have varying requirements depending on the location of the teacher. This is probably due to some combination of local regulations, fraud protection, and other things we don’t need to worry about.</p>

<p>So, before we create a Payment Intent, we need to know where the teacher is located — or more specifically, where her bank account is located.</p>

<p>Stripe has this information — and instead of making an API call to Stripe before creating every payment intent (to find the  user’s location), we’ll save the location in our database.</p>

<h3 id="location-differences">Location Differences</h3>

<p>From Stripe’s docs:</p>

<blockquote>
  <p>Since cross-border transfers are not supported in countries outside your region, some accounts will need to use the card payments capability and act as the settlement merchant to process payments.</p>
</blockquote>

<p>So, when the teacher’s country differs from the platform country (this is our location, USA), the platform can no longer act as a middle man in the transaction — the teacher becomes the settlement merchant.</p>

<p>This distinction may seem confusing and boring, so we won’t linger here, other than to say that we need to specify something about <em>card payments</em> later on, when the teacher’s country differs from ours.</p>

<h3 id="payment-intents">Payment Intents</h3>

<p>Here’s what a generic Payment Intent might look like in Ruby:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code>
<span class="n">pay_int</span> <span class="o">=</span> <span class="no">Stripe</span><span class="o">::</span><span class="no">PaymentIntent</span><span class="p">.</span><span class="nf">create</span><span class="p">({</span>
			<span class="ss">amount: </span><span class="n">amount</span><span class="p">,</span>
			<span class="ss">customer: </span><span class="n">student</span><span class="p">.</span><span class="nf">stripe_student_id</span><span class="p">,</span>
			<span class="ss">currency: </span><span class="s1">'usd'</span><span class="p">,</span>
			<span class="ss">payment_method: </span><span class="n">customer_payment_method</span><span class="p">,</span>
			<span class="ss">off_session: </span><span class="kp">true</span><span class="p">,</span>
			<span class="ss">confirm: </span><span class="kp">true</span><span class="p">,</span>
			<span class="n">transfer_data</span><span class="p">:{</span>
				<span class="ss">destination: </span><span class="n">teacher</span><span class="p">.</span><span class="nf">stripe_teacher_id</span><span class="p">,</span>
				<span class="ss">amount: </span><span class="n">transfer_amount</span>
			<span class="p">}</span>
		<span class="p">})</span>
</code></pre></div></div>

<p>The first few parameters (<code class="language-plaintext highlighter-rouge">amount</code>, <code class="language-plaintext highlighter-rouge">customer</code>, <code class="language-plaintext highlighter-rouge">currency</code>, <code class="language-plaintext highlighter-rouge">payment_method</code>) are fairly straightforward.</p>

<p><code class="language-plaintext highlighter-rouge">off_session: true</code> means the student isn’t present in the checkout flow, which is half true for us — technically he might be present, but his saved card is automatically charged when a session ends.</p>

<p><code class="language-plaintext highlighter-rouge">confirm: true</code> means it’s go time, we’re ready to charge.</p>

<p><code class="language-plaintext highlighter-rouge">transfer_data</code> is the crucial parameter — this is how the platform operates, by transferring money from one person to another (minus the platform fee).</p>

<h3 id="cross-border-transfer">Cross border transfer</h3>

<p>If a Mexican teacher helps a Japanese student, we need to use the <em>card payments</em> capability. Stripe Connect will automatically enable this for international accounts in the admin (for Express accounts, at least).</p>

<p>As mentioned in the docs, <em>card payments</em> allows teachers to receive funds directly from students, without the platform acting as an intermediary.</p>

<p>If you’re wondering why we don’t treat domestic transfers this way — the reason is that the account setup for a teacher is significantly more of a pain when they need to act as a <em>settlement merchant</em>. If the platform acts as the <em>settlement merchant</em>, things are easier for everyone involved.</p>

<p><em>Card Payments</em> are already enabled in the admin (for international teachers), but we also have to specify this directly in the <em>Payment Intent</em>. To do this, we include an additional parameter <code class="language-plaintext highlighter-rouge">on_behalf_of</code> — this specifies that the teacher will be the <em>settlement merchant</em> for this transaction.</p>

<p>However, we don’t want to have one <code class="language-plaintext highlighter-rouge">Stripe::PaymentIntent.create</code> flow for US teachers and another <code class="language-plaintext highlighter-rouge">Stripe::PaymentIntent.create</code> for International teachers, because we’d be repeating ourselves and risking a DRY violation.</p>

<h3 id="rubys-tap">Ruby’s <code class="language-plaintext highlighter-rouge">tap</code></h3>

<p><code class="language-plaintext highlighter-rouge">tap</code> is a ruby method that allows us to … <em>tap</em> into attributes of an object or the keys of a hash.</p>

<p>For example, when creating a new user, we could do something like this:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">user</span> <span class="o">=</span> <span class="no">User</span><span class="p">.</span><span class="nf">new</span><span class="p">.</span><span class="nf">tap</span> <span class="k">do</span> <span class="o">|</span><span class="n">u</span><span class="o">|</span>
  <span class="n">u</span><span class="p">.</span><span class="nf">username</span> <span class="o">=</span> <span class="s2">"horat22"</span>
  <span class="n">u</span><span class="p">.</span><span class="nf">name</span> <span class="o">=</span> <span class="s2">"Horatio"</span>
  <span class="n">u</span><span class="p">.</span><span class="nf">location</span> <span class="o">=</span> <span class="s2">"Earth"</span>
  <span class="n">u</span><span class="p">.</span><span class="nf">save</span>
<span class="k">end</span>
</code></pre></div></div>

<p>This mini-bind that we’re in with Stripe presents a great opportunity for <code class="language-plaintext highlighter-rouge">tap</code>, since we can <em>conditionally</em> decide whether to add a particular attribute.</p>

<p>And we only want to include the <code class="language-plaintext highlighter-rouge">on_behalf_of</code> sometimes, in the case of the cross-border payment mentioned above.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">obj</span> <span class="o">=</span> <span class="p">{</span>
	<span class="ss">amount: </span><span class="n">amount</span><span class="p">,</span>
	<span class="ss">customer: </span><span class="n">student</span><span class="p">.</span><span class="nf">stripe_student_id</span><span class="p">,</span>
	<span class="ss">currency: </span><span class="s1">'usd'</span><span class="p">,</span>
	<span class="ss">payment_method: </span><span class="n">customer_payment_method</span><span class="p">,</span>
	<span class="ss">off_session: </span><span class="kp">true</span><span class="p">,</span>
	<span class="ss">confirm: </span><span class="kp">true</span><span class="p">,</span>
	<span class="n">transfer_data</span><span class="p">:{</span>
	  <span class="ss">destination: </span><span class="n">teacher</span><span class="p">.</span><span class="nf">stripe_teacher_id</span><span class="p">,</span>
	  <span class="ss">amount: </span><span class="n">transfer_amount</span>
	<span class="p">}</span>
<span class="p">}</span>

<span class="n">obj</span><span class="p">.</span><span class="nf">tap</span> <span class="k">do</span> <span class="o">|</span><span class="nb">hash</span><span class="o">|</span>
	<span class="nb">hash</span><span class="p">[</span><span class="ss">:on_behalf_of</span><span class="p">]</span> <span class="o">=</span> <span class="n">teacher</span><span class="p">.</span><span class="nf">stripe_teacher_id</span> <span class="k">if</span> <span class="n">not_us</span><span class="p">(</span><span class="n">teacher</span><span class="p">.</span><span class="nf">country</span><span class="p">)</span>
<span class="k">end</span>

<span class="n">pi</span> <span class="o">=</span> <span class="no">Stripe</span><span class="o">::</span><span class="no">PaymentIntent</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="n">obj</span><span class="p">)</span>

</code></pre></div></div>

<p>We have a helper method <code class="language-plaintext highlighter-rouge">not_us</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code>  <span class="k">def</span> <span class="nf">not_us</span><span class="p">(</span><span class="n">country</span><span class="p">)</span>
    <span class="n">country</span> <span class="o">!=</span> <span class="s1">'US'</span> <span class="o">&amp;&amp;</span> <span class="o">!</span><span class="n">country</span><span class="p">.</span><span class="nf">nil?</span>
  <span class="k">end</span>
</code></pre></div></div>

<p>which returns <code class="language-plaintext highlighter-rouge">true</code> if the teacher’s bank account is <strong>not</strong> located in the USA.</p>

<p>To recap - we first <code class="language-plaintext highlighter-rouge">tap</code> into our <code class="language-plaintext highlighter-rouge">obj</code> which contains the Payment Intent data. Then we decide whether we want to add <code class="language-plaintext highlighter-rouge">:on_behalf_of</code>. Then, we pass <code class="language-plaintext highlighter-rouge">obj</code> into <code class="language-plaintext highlighter-rouge">Stripe::PaymentIntent.create</code>.</p>

<p>Ruby’s <code class="language-plaintext highlighter-rouge">tap</code> has allowed us to maintain a single payment flow, and keep our code DRY.</p>

<h3 id="conclusion">Conclusion</h3>

<p>That’s all for now.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Location Quirks and DRY Code]]></summary></entry><entry><title type="html">Git Save</title><link href="https://unfoundedlabs.com/blog/git_save" rel="alternate" type="text/html" title="Git Save" /><published>2021-05-04T00:00:00+00:00</published><updated>2021-05-04T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/git-save</id><content type="html" xml:base="https://unfoundedlabs.com/blog/git_save"><![CDATA[<h3 id="autosave">Autosave</h3>

<p>Back in the days before everything auto-saved, we actually had to remember to save things.</p>

<p>It wasn’t all that painful, aside from the occasional unsaved app crashing fiasco. It gave a moment to pause, reflect, and mark a point in progress.</p>

<p>Autosave has eliminated these pause breaks for nearly all computer-related work, though one exception comes to mind: programming.</p>

<p>Version control forces us to pause every now and again, and deliberately mark a save point for our work. Whether or not this pause break is a peaceful moment of reflection is another question.</p>

<p>These pause breaks look something like:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git add -A
git c -m 'my commit message'
git push
</code></pre></div></div>

<p>This is fine, but it can be a bit tedious - <em>stage</em>, <em>commit</em>, <em>push</em> each time.</p>

<p>The temporary pause is refreshing, though perhaps we can reduce the number of steps required.</p>

<p>Let’s try to make our pause-break resemble a single <code class="language-plaintext highlighter-rouge">command S</code>.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git save
</code></pre></div></div>

<p>Here’s how:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config --global alias.save '!f() { message=${1:-"default message"}; git add -A &amp;&amp; git commit -m "$message" &amp;&amp; git push; }; f'
</code></pre></div></div>

<p>This works right out of the box. Typing <code class="language-plaintext highlighter-rouge">git save</code> will stage all files, create a commit with “default message” (or whatever we replace “default message” with), and then push the files.</p>

<p>If we want to specify the commit message, we can say <code class="language-plaintext highlighter-rouge">git save 'my custom message'</code> and we’re on our way.</p>

<h3 id="how">How</h3>

<p>Create the git alias <code class="language-plaintext highlighter-rouge">save</code></p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config --global alias.save
</code></pre></div></div>

<p>Create a shell function and then call it.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>'!f() { ... }; f'
</code></pre></div></div>

<p>Create a default message, or take one is as the first argument.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>message=${1:-"default message"};
</code></pre></div></div>

<p>Stage, commit, and then push.</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git add -A &amp;&amp; git commit -m "$message" &amp;&amp; git push; 
</code></pre></div></div>

<p>And altogether again:</p>

<div class="language-plaintext highlighter-rouge"><div class="highlight"><pre class="highlight"><code>git config --global alias.save '!f() { message=${1:-"default message"}; git add -A &amp;&amp; git commit -m "$message" &amp;&amp; git push; }; f'
</code></pre></div></div>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Autosave]]></summary></entry><entry><title type="html">HTML Whitespace problems</title><link href="https://unfoundedlabs.com/blog/whitespace-child" rel="alternate" type="text/html" title="HTML Whitespace problems" /><published>2021-03-30T00:00:00+00:00</published><updated>2021-03-30T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/whitespace-firstchild</id><content type="html" xml:base="https://unfoundedlabs.com/blog/whitespace-child"><![CDATA[<h3 id="lessons-from-html-passed-over-the-wire-in-rails">Lessons from HTML passed Over The Wire in Rails</h3>

<p>Our app is a web chat - so a variety of data needs to be broadcasted directly to a user in real time.</p>

<p>This is handled via WebSockets - instant sending and receiving of data. Rails implementation of WS is called <code class="language-plaintext highlighter-rouge">Action Cable</code>.</p>

<h3 id="incoming-requests">Incoming Requests</h3>

<p>For this <a href="https://bouncerip.com">chat application</a>, users can request chats with <em>pros</em>.</p>

<p>So a pro will receive an incoming request on her dashboard.</p>

<p>Before request:</p>

<p><img src="/assets/images/blog/request1.png" alt="" /></p>

<p>After request:</p>

<p><img src="/assets/images/blog/request2.png" alt="" /></p>

<p>As mentioned above, we need to send this data directly to the pro, without the pro needing to refresh her page.</p>

<p>Let’s look in the Controller that handles chat sessions.</p>

<h3 id="chatsessions-controller">ChatSessions Controller</h3>

<p>When a user requests a chat, we route to the <code class="language-plaintext highlighter-rouge">create</code> action of the <code class="language-plaintext highlighter-rouge">ChatSessionsController</code></p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1"># ChatSessionsController</span>

<span class="k">def</span> <span class="nf">create</span>
	<span class="o">...</span>
	<span class="c1"># append new student to pro buddy list</span>
	<span class="no">SessionChannel</span><span class="p">.</span><span class="nf">broadcast_to</span><span class="p">(</span>
	    <span class="vi">@pro</span><span class="p">,</span>
	    <span class="ss">action: </span><span class="s1">'create'</span><span class="p">,</span>
	    <span class="ss">new_student: </span><span class="n">new_student</span><span class="p">(</span><span class="vi">@chat_session</span><span class="p">),</span>
	    <span class="o">...</span> <span class="n">more</span> <span class="n">stuff</span> <span class="o">...</span>
	  <span class="p">)</span>
	<span class="o">...</span>
<span class="k">end</span>

<span class="kp">private</span>

<span class="k">def</span> <span class="nf">new_student</span><span class="p">(</span><span class="n">session</span><span class="p">)</span>
	<span class="no">ApplicationController</span><span class="p">.</span><span class="nf">renderer</span><span class="p">.</span><span class="nf">render</span><span class="p">(</span><span class="ss">partial: </span><span class="s1">'shared/list_user_pro_dash'</span><span class="p">,</span> <span class="ss">locals: </span><span class="p">{</span> <span class="ss">session: </span><span class="n">session</span><span class="p">,</span> <span class="ss">session_status: </span><span class="s1">'active'</span> <span class="p">})</span>
<span class="k">end</span>
</code></pre></div></div>

<p>The <code class="language-plaintext highlighter-rouge">SessionChannel</code> is the Action Cable channel where we handle chat sessions throughout their lifecycle (<code class="language-plaintext highlighter-rouge">request</code>, <code class="language-plaintext highlighter-rouge">accept</code>, <code class="language-plaintext highlighter-rouge">cancel</code>, <code class="language-plaintext highlighter-rouge">end</code>).</p>

<p>In this case, we are broadcasting an HTML partial (<code class="language-plaintext highlighter-rouge">list_user_pro_dash.html.erb</code>) directly to the <code class="language-plaintext highlighter-rouge">@pro</code>’s dashboard.</p>

<p>This partial generates the HTML we see in the image above — a link with the username of the incoming request.</p>

<h3 id="receiving-the-partial">Receiving the Partial</h3>

<p>The Javascript component of the <code class="language-plaintext highlighter-rouge">SessionChannel</code> lives in <code class="language-plaintext highlighter-rouge">session_channel.js</code>, and we <code class="language-plaintext highlighter-rouge">receive</code> the data that was broadcasted from the controller.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">#session_channel.js</span>

<span class="n">import</span> <span class="n">consumer</span> <span class="n">from</span> <span class="s2">"./consumer"</span>

<span class="n">consumer</span><span class="p">.</span><span class="nf">subscriptions</span><span class="p">.</span><span class="nf">create</span><span class="p">(</span><span class="s2">"SessionChannel"</span><span class="p">,</span> <span class="p">{</span>
  <span class="n">connected</span><span class="p">()</span> <span class="p">{},</span>
  <span class="n">disconnected</span><span class="p">()</span> <span class="p">{},</span>
  <span class="n">received</span><span class="p">(</span><span class="n">data</span><span class="p">)</span> <span class="p">{</span>
	  <span class="k">if</span> <span class="p">(</span><span class="n">data</span><span class="p">.</span><span class="nf">action</span> <span class="o">==</span> <span class="s1">'create'</span><span class="p">){</span>
	  <span class="sr">//</span> <span class="n">append</span> <span class="n">data</span><span class="p">.</span><span class="nf">new_student</span> <span class="n">to</span> <span class="n">correct</span> <span class="n">location</span> <span class="k">in</span> <span class="no">DOM</span>
	 <span class="p">}</span>
<span class="p">})</span>
</code></pre></div></div>

<h3 id="appending-datanew_student">Appending <code class="language-plaintext highlighter-rouge">data.new_student</code></h3>

<p><code class="language-plaintext highlighter-rouge">data.new_student</code> is a string that contains the <code class="language-plaintext highlighter-rouge">HTML</code> corresponding to this requested chat. Just a minute ago, this was rendered via <code class="language-plaintext highlighter-rouge">ApplicationController.renderer</code> in our <code class="language-plaintext highlighter-rouge">ChatSessionsController</code>.</p>

<p>To append it to the pro’s dashboard, we could do something like this:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">new_student</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">new_student</span>

<span class="c1">// active sessions live in #active element</span>
<span class="kd">const</span> <span class="nx">active</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">active</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">active</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">new_student</span><span class="p">)</span>
</code></pre></div></div>

<p>However, this won’t work because <code class="language-plaintext highlighter-rouge">new_student</code> is a string (and not a Node element), so <code class="language-plaintext highlighter-rouge">append</code> will treat it like a string.</p>

<p>In other words, we will see HTML, instead of experiencing HTML.</p>

<p>In other words, actually, in images, our view will look something like:</p>

<p><img src="/assets/images/blog/request4.png" alt="" /></p>

<p>instead of what we want:</p>

<p><img src="/assets/images/blog/request3.png" alt="" /></p>

<h3 id="strings-or-nodes">Strings or Nodes</h3>

<p>So at this point, we either need to turn our HTML string into a Node object (because <code class="language-plaintext highlighter-rouge">append</code> can also append nodes) or somehow ask Javascript to interpret our string as HTML.</p>

<p>The latter option probably would have been the easiest. All we would have to do is something like this:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">new_student</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">new_student</span>

<span class="c1">// active sessions live in #active element</span>
<span class="kd">const</span> <span class="nx">active</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">active</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">active</span><span class="p">.</span><span class="nf">insertAdjacentHTML</span><span class="p">(</span><span class="dl">'</span><span class="s1">beforeend</span><span class="dl">'</span><span class="p">,</span> <span class="nx">new_student</span><span class="p">)</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">insertAdjacentHTML</code> will parse a string as HTML.</p>

<p>However, I decided to stick with <code class="language-plaintext highlighter-rouge">append</code> to see if we could get it to work.</p>

<p>To do this, we do a little hack: we create an element, then fill it with our HTML string. At this point, our string magically becomes a node object. And we can extract it from our temporary element (<code class="language-plaintext highlighter-rouge">temp_obj</code>) via <code class="language-plaintext highlighter-rouge">firstChild</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// create temp Node object</span>
<span class="kd">const</span> <span class="nx">temp_obj</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">temp_obj</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">new_student</span>
<span class="kd">const</span> <span class="nx">new_student</span> <span class="o">=</span> <span class="nx">temp_obj</span><span class="p">.</span><span class="nx">firstChild</span>

<span class="c1">// append to list</span>
<span class="kd">const</span> <span class="nx">active</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">active</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">active</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">new_student</span><span class="p">)</span>
</code></pre></div></div>

<p>At this point we have a working solution. We turn a string of HTML from our Controller into a node, and then append it to the correct element.</p>

<h3 id="the-application-breaks">The Application Breaks</h3>

<p>Initially, the partial we append (<code class="language-plaintext highlighter-rouge">new_student</code>) looked something like this:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;li&gt;</span>Stuff in here<span class="nt">&lt;/li&gt;</span>
</code></pre></div></div>

<p>Then, we make a seemingly innocuous change to the partial.</p>

<div class="language-erb highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;%</span> <span class="k">if</span> <span class="n">something?</span> <span class="cp">%&gt;</span>
	<span class="nt">&lt;li&gt;</span>Stuff in here<span class="nt">&lt;/li&gt;</span>
<span class="cp">&lt;%</span> <span class="k">else</span> <span class="cp">%&gt;</span>
	<span class="nt">&lt;li&gt;</span>Different stuff in here<span class="nt">&lt;/li&gt;</span>
<span class="cp">&lt;%</span> <span class="k">end</span> <span class="cp">%&gt;</span>
</code></pre></div></div>

<p>Now the application is broken.</p>

<h3 id="huh">Huh?</h3>

<p>It seemed bizarre that the addition of a conditional in a partial on the backend would break the broadcasting elsewhere in the site.</p>

<p>It turns out that the broadcast wasn’t broken, but our Javascript was unable to deal with the new HTML string from our partial.</p>

<h3 id="whats-new-in-this-partial">What’s new in this partial?</h3>

<p>It would seem that the partial should render a virtually identical result — a simple <code class="language-plaintext highlighter-rouge">&lt;li&gt;</code> element containing some info.</p>

<p>However, there is one difference. As is standard in code syntax, we indent the nested line inside of a conditional.</p>

<p>And because of this, a whitespace is created before our <code class="language-plaintext highlighter-rouge">&lt;li&gt;</code> element.</p>

<h3 id="firstchild">FirstChild</h3>

<p>Now back to our Javascript. Our <code class="language-plaintext highlighter-rouge">data.new_student</code> now contains a single whitespace, and then an <code class="language-plaintext highlighter-rouge">&lt;li&gt;</code> element.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// temporary object</span>
<span class="kd">const</span> <span class="nx">temp_obj</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">temp_obj</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">new_student</span>
<span class="kd">const</span> <span class="nx">new_student</span> <span class="o">=</span> <span class="nx">temp_obj</span><span class="p">.</span><span class="nx">firstChild</span>

<span class="kd">const</span> <span class="nx">active</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">active</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">active</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">new_student</span><span class="p">)</span>
</code></pre></div></div>

<p>When we temporarily created the element and then grab the <code class="language-plaintext highlighter-rouge">firstChild</code>, we are actually grabbing the whitespace instead of the <code class="language-plaintext highlighter-rouge">&lt;li&gt;</code>.</p>

<p>So, we are appending something, but we are appending whitespace.</p>

<h3 id="fixes">Fixes</h3>

<p>At this point we have a couple of fixes.</p>

<p>The easiest would be to use <code class="language-plaintext highlighter-rouge">firstElementChild</code> instead of <code class="language-plaintext highlighter-rouge">firstChild</code>, as that will grab the <code class="language-plaintext highlighter-rouge">&lt;li&gt;</code> and ignore text(whitespace).</p>

<p>Alternatively, we can be more specific than <code class="language-plaintext highlighter-rouge">firstElementChild</code> and instead look directly for an <code class="language-plaintext highlighter-rouge">&lt;li&gt;</code> element.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// temporary element</span>
<span class="kd">const</span> <span class="nx">wrapper</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">div</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">wrapper</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">=</span> <span class="nx">data</span><span class="p">.</span><span class="nx">new_student</span>
<span class="kd">const</span> <span class="nx">new_student</span> <span class="o">=</span> <span class="nx">wrapper</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">"</span><span class="s2">li</span><span class="dl">"</span><span class="p">)</span>

<span class="kd">const</span> <span class="nx">active</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementById</span><span class="p">(</span><span class="dl">'</span><span class="s1">active</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">active</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">new_student</span><span class="p">)</span>
</code></pre></div></div>

<h3 id="the-end">The End</h3>

<p>Be careful when using <code class="language-plaintext highlighter-rouge">firstChild</code> as whitespace could potentially find its way to the front of the child you were initially targeting.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Lessons from HTML passed Over The Wire in Rails]]></summary></entry><entry><title type="html">Graceful Ruby Exits</title><link href="https://unfoundedlabs.com/blog/ruby-exits" rel="alternate" type="text/html" title="Graceful Ruby Exits" /><published>2021-02-08T00:00:00+00:00</published><updated>2021-02-08T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/ruby-exits</id><content type="html" xml:base="https://unfoundedlabs.com/blog/ruby-exits"><![CDATA[<h3 id="exceptions-rescues-and-error-handling">Exceptions, rescues, and error handling</h3>

<p>Let’s say we’re running this simple little Ruby program:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">i</span> <span class="o">=</span> <span class="mi">0</span>
<span class="kp">loop</span> <span class="k">do</span>
	<span class="nb">exit</span> <span class="k">if</span> <span class="n">i</span> <span class="o">==</span> <span class="mi">5</span>
	<span class="nb">puts</span> <span class="s1">'Doing something'</span>
	<span class="n">i</span> <span class="o">+=</span> <span class="mi">1</span>
	<span class="nb">sleep</span> <span class="mi">10</span>
<span class="k">end</span>
</code></pre></div></div>

<p>This will print <em>Doing something</em> every 10 seconds, five times, and then exit.</p>

<p>A different, more relatable example of this might be if we we want to run something continuously until a given time.</p>

<p>In that case, it might look like:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="n">y</span> <span class="o">=</span> <span class="mi">2030</span><span class="p">;</span> <span class="n">mo</span> <span class="o">=</span> <span class="mi">2</span><span class="p">;</span> <span class="n">d</span> <span class="o">=</span> <span class="mi">28</span><span class="p">;</span> <span class="n">h</span> <span class="o">=</span> <span class="mi">17</span><span class="p">;</span> <span class="n">mi</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
<span class="n">cutoff</span> <span class="o">=</span> <span class="no">Time</span><span class="p">.</span><span class="nf">new</span><span class="p">(</span><span class="n">y</span><span class="p">,</span> <span class="n">mo</span><span class="p">,</span> <span class="n">d</span><span class="p">,</span> <span class="n">h</span><span class="p">,</span> <span class="n">mi</span><span class="p">)</span>
<span class="kp">loop</span> <span class="k">do</span>
	<span class="nb">exit</span> <span class="k">if</span> <span class="no">Time</span><span class="p">.</span><span class="nf">now</span> <span class="o">&gt;</span> <span class="n">cutoff</span>
	<span class="nb">puts</span> <span class="s1">'Doing something'</span>
	<span class="nb">sleep</span> <span class="mi">10</span>
<span class="k">end</span>
</code></pre></div></div>

<p>In this case, we’ll print <em>Doing something</em> every 10 seconds until February 28, 2030 at 5PM. Here’s a <a href="https://repl.it/@eri_b/2030">link</a> to a working program if you’d like to run this until 2030.</p>

<h3 id="manual-exit">Manual Exit</h3>

<p>In these examples, the programs would automatically exit at some point via an <code class="language-plaintext highlighter-rouge">exit</code> statement.</p>

<p>Let’s say we want to exit earlier; we can manually force an exit by running <code class="language-plaintext highlighter-rouge">CTRL C</code> in our Terminal.</p>

<h3 id="exit-cleanup">Exit Cleanup</h3>

<p>When our program exits, either automatically or manually, we might want to do some clean up.</p>

<p>Let’s say our program is a stock trading bot. When we exit, we want to make sure all the positions are closed.</p>

<p>Luckily, we can use Ruby’s <code class="language-plaintext highlighter-rouge">at_exit</code> block to handle this.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">at_exit</span> <span class="k">do</span>
	<span class="c1"># close all positions</span>
<span class="k">end</span>
</code></pre></div></div>

<p>This will run, as we’d expect, when the program ends. We just need to make sure this is defined before <code class="language-plaintext highlighter-rouge">exit</code> is called, or it won’t be found.</p>

<h3 id="exceptions">Exceptions</h3>

<p>When we exit the program early via the <code class="language-plaintext highlighter-rouge">CTRL C</code> method, everything seems to operate normally, but we also notice that we receive a messy error message in our Terminal.</p>

<p>This is because <code class="language-plaintext highlighter-rouge">CTRL C</code> triggers a <code class="language-plaintext highlighter-rouge">SignalException</code> and the program terminates. When exceptions are unhandled, our Terminal spews out some stuff that’s supposed to help us out.</p>

<p>If we want to exit the program more gracefully during a <code class="language-plaintext highlighter-rouge">CTRL C</code>, we can rescue ourselves from this <code class="language-plaintext highlighter-rouge">SignalException</code> using a <code class="language-plaintext highlighter-rouge">begin</code> - <code class="language-plaintext highlighter-rouge">rescue</code> block.</p>

<h3 id="begin--rescue-detour">Begin / Rescue Detour</h3>

<p>The boilerplate <code class="language-plaintext highlighter-rouge">begin</code> - <code class="language-plaintext highlighter-rouge">rescue</code> block looks something like this:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">begin</span>
	<span class="c1"># do something bad</span>
	<span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="k">rescue</span>
	<span class="s1">'something bad happened'</span>
<span class="k">end</span>
</code></pre></div></div>

<p>If we want to know what the bad thing was, we can pass the exception object into the rescue.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">begin</span>
	<span class="c1"># do something naughty</span>
	<span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="k">rescue</span> <span class="o">=&gt;</span> <span class="n">e</span>
	<span class="nb">puts</span> <span class="n">e</span><span class="p">.</span><span class="nf">message</span>
<span class="k">end</span>
</code></pre></div></div>

<p>This will print:</p>

<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>divided by 0
</code></pre></div></div>

<p>In addition to <code class="language-plaintext highlighter-rouge">message</code>, there are a variety of instance methods available to call on our exception object (<code class="language-plaintext highlighter-rouge">full_message</code>, <code class="language-plaintext highlighter-rouge">backtrace</code>, etc) to give us whatever info we might want.</p>

<p>One other thing worth mentioning — method declarations are implicit <code class="language-plaintext highlighter-rouge">begin</code> blocks, so we can do something like this:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">def</span> <span class="nf">my_method</span>
	<span class="mi">1</span> <span class="o">/</span> <span class="mi">0</span>
<span class="k">rescue</span>
	<span class="nb">puts</span> <span class="s1">'Something bad'</span>
<span class="k">end</span>
</code></pre></div></div>

<p>(And so are <code class="language-plaintext highlighter-rouge">Class</code> and <code class="language-plaintext highlighter-rouge">Module</code> declarations.)</p>

<p>Why do we keep using <code class="language-plaintext highlighter-rouge">1/0</code> as an example? It’s a quick way to trigger an Exception, as programs (just like calculators) cannot divide numbers by zero.</p>

<h3 id="one-large-caveat">One Large Caveat</h3>

<p>If we don’t specify the Exception type on our <code class="language-plaintext highlighter-rouge">rescue</code> it will default to a <code class="language-plaintext highlighter-rouge">StandardError</code>.</p>

<p>So</p>
<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">begin</span>
	<span class="c1"># do something bad</span>
	<span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="k">rescue</span>
	<span class="s1">'something bad happened'</span>
<span class="k">end</span>
</code></pre></div></div>

<p>is identical to</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">begin</span>
	<span class="c1"># do something bad</span>
	<span class="mi">1</span><span class="o">/</span><span class="mi">0</span>
<span class="k">rescue</span> <span class="no">StandardError</span>
	<span class="s1">'something bad happened'</span>
<span class="k">end</span>
</code></pre></div></div>

<p><code class="language-plaintext highlighter-rouge">StandardError</code> is an umbrella Error class, that contains many of the <em>standard</em> exceptions, and as we’ve seen above, <code class="language-plaintext highlighter-rouge">ZeroDivisionError</code> is one of these. There are a dozen or so of these children - <a href="https://ruby-doc.org/core-2.5.1/Exception.html">link here</a>.</p>

<p>However, the exception created by a <code class="language-plaintext highlighter-rouge">CTRL C</code>, <code class="language-plaintext highlighter-rouge">SignalException</code>, is NOT a child of <code class="language-plaintext highlighter-rouge">StandardError</code>, so it will not be handled by the default <code class="language-plaintext highlighter-rouge">rescue</code>. We have to specifically handle this scenario.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="k">begin</span>
	<span class="c1"># Code here</span>
<span class="k">rescue</span> <span class="no">SignalException</span>
	<span class="nb">puts</span> <span class="s2">"CTRL C"</span>
<span class="k">rescue</span>
	<span class="nb">puts</span> <span class="s2">"StandardError"</span>
<span class="k">end</span>
</code></pre></div></div>

<h3 id="rescuing-signalexception">Rescuing SignalException</h3>

<p>Now that we’re able to rescue <code class="language-plaintext highlighter-rouge">SignalException</code>, our terminal won’t freak out when we <code class="language-plaintext highlighter-rouge">CTRL C</code>.</p>

<p>However, we need to be careful about how we exit at this point.</p>

<p>Since we’re rescuing from this exception, the program will not automatically exit anymore. We need to explicitly tell it to exit.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">at_exit</span> <span class="k">do</span>
	<span class="c1"># clean up program</span>
<span class="k">end</span>

<span class="k">begin</span>
	<span class="c1"># Code here</span>
<span class="k">rescue</span> <span class="no">SignalException</span>
	<span class="nb">puts</span> <span class="s2">"Program terminated via CTRL C"</span>
	<span class="nb">exit</span>
<span class="k">rescue</span>
	<span class="nb">puts</span> <span class="s2">"StandardError"</span>
<span class="k">end</span>
</code></pre></div></div>

<p>You might be wondering if adding that explicit <code class="language-plaintext highlighter-rouge">exit</code> statement was necessary. The answer is — sort of.</p>

<h3 id="the-third-exit">The Third Exit</h3>

<p>So far, we’ve seen exits from <code class="language-plaintext highlighter-rouge">CTRL C</code> and <code class="language-plaintext highlighter-rouge">exit</code> statements in our code. Another way a program will exit is when it simply reaches the end of the program.</p>

<p>Back to the question above - we might get away with not calling <code class="language-plaintext highlighter-rouge">exit</code> in our <code class="language-plaintext highlighter-rouge">SignalException</code> if the program will exit on its own immediately after.</p>

<p>When the program exits on its own, <code class="language-plaintext highlighter-rouge">at_exit</code> is still called, and everything goes as planned.</p>

<p>But it pays to be explicit in this case, because there’s a chance there could be something that happens <em>after</em> the <code class="language-plaintext highlighter-rouge">begin</code> - <code class="language-plaintext highlighter-rouge">rescue</code> block, but <em>before</em> the program naturally concludes and exits.</p>

<p>For example:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">at_exit</span> <span class="k">do</span>
	<span class="nb">puts</span> <span class="s2">"in at_exit"</span>
<span class="k">end</span>

<span class="k">begin</span>
	<span class="nb">sleep</span> <span class="mi">10</span>
<span class="k">rescue</span> <span class="no">SignalException</span>
	<span class="nb">puts</span> <span class="s2">"Program terminated via CTRL C"</span>
	<span class="c1"># no exit call here</span>
<span class="k">end</span>

<span class="nb">sleep</span> <span class="mi">100</span>
</code></pre></div></div>

<p>This program will initially sleep for 10 seconds. If we call <code class="language-plaintext highlighter-rouge">CTRL C</code> during this 10 seconds, we will be rescued, but we have removed the <code class="language-plaintext highlighter-rouge">exit</code> call.</p>

<p>Now the program won’t exit right away. <code class="language-plaintext highlighter-rouge">at_exit</code> won’t run for 100 seconds.</p>

<p>If we add back the <code class="language-plaintext highlighter-rouge">exit</code> call in our <code class="language-plaintext highlighter-rouge">SignalException</code>, we can guarantee that we immediately exit when <code class="language-plaintext highlighter-rouge">CTRL C</code> is called.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">at_exit</span> <span class="k">do</span>
	<span class="nb">puts</span> <span class="s2">"in at_exit"</span>
<span class="k">end</span>

<span class="k">begin</span>
	<span class="nb">sleep</span> <span class="mi">10</span>
<span class="k">rescue</span> <span class="no">SignalException</span>
	<span class="nb">puts</span> <span class="s2">"Program terminated via CTRL C"</span>
	<span class="nb">exit</span>
<span class="k">end</span>
</code></pre></div></div>

<h3 id="one-last-rescue">One Last Rescue</h3>

<p>Everything should be working nicely now. For clarity, we’ll add one last rescue statement.</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nb">at_exit</span> <span class="k">do</span>
	<span class="nb">puts</span> <span class="s2">"in at_exit"</span>
<span class="k">end</span>

<span class="k">begin</span>
	<span class="nb">sleep</span> <span class="mi">10</span>
	<span class="nb">exit</span>
<span class="k">rescue</span> <span class="no">SignalException</span>
	<span class="nb">puts</span> <span class="s2">"Program terminated via CTRL C"</span>
	<span class="nb">exit</span>
<span class="k">rescue</span> <span class="no">SystemExit</span>
	<span class="nb">puts</span> <span class="s2">"Program terminated via exit command"</span>
	<span class="nb">exit</span>
<span class="k">rescue</span> <span class="o">=&gt;</span> <span class="n">e</span>
	<span class="nb">puts</span> <span class="s2">"StandardError"</span>
	<span class="nb">puts</span> <span class="n">e</span><span class="p">.</span><span class="nf">message</span>
<span class="k">end</span>
</code></pre></div></div>

<p>This step isn’t completely necessary, but I think it helps understand what’s happening. We’ve added a <code class="language-plaintext highlighter-rouge">SystemExit</code> rescue, which captures any <code class="language-plaintext highlighter-rouge">exit</code> statement in our <code class="language-plaintext highlighter-rouge">begin</code> block. As you may have expected, <code class="language-plaintext highlighter-rouge">SystemExit</code> is not a child of <code class="language-plaintext highlighter-rouge">StandardError</code>, so we have to explicitly declare it.</p>

<p>This is helpful because we receive information about <em>how</em> the program exited. Every time the program exits, we’ll know whether it came from an <code class="language-plaintext highlighter-rouge">exit</code> call or from a <code class="language-plaintext highlighter-rouge">CTRL C</code>.</p>

<p>And again, since we’re capturing this in a rescue block, we have to explicitly <code class="language-plaintext highlighter-rouge">exit</code> for the same reasons as mentioned above.</p>

<h3 id="the-end">The end</h3>

<p>Our program can exit via (1) an <code class="language-plaintext highlighter-rouge">exit</code> statement in the <code class="language-plaintext highlighter-rouge">begin</code> block, (2) a <code class="language-plaintext highlighter-rouge">CTRL C</code> user input, or (3) by reaching the end of the program.</p>

<p>(1) is captured by a <code class="language-plaintext highlighter-rouge">SystemExit</code> and explicitly exited.
(2) is captured by a <code class="language-plaintext highlighter-rouge">SignalException</code> and explicitly exited.</p>

<p>(1),(2), and (3) find their way to the <code class="language-plaintext highlighter-rouge">at_exit</code> block, allowing us to clean things up.</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Exceptions, rescues, and error handling]]></summary></entry><entry><title type="html">Appending and Inserting in Javascript</title><link href="https://unfoundedlabs.com/blog/javascript-append" rel="alternate" type="text/html" title="Appending and Inserting in Javascript" /><published>2021-01-24T00:00:00+00:00</published><updated>2021-01-24T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/appending-javascript</id><content type="html" xml:base="https://unfoundedlabs.com/blog/javascript-append"><![CDATA[<p><span class="note">This post also lives over at <a href="https://css-tricks.com/comparing-methods-for-appending-and-inserting-with-javascript/" target="_blank">CSS Tricks</a></span></p>

<p>Let’s say we want to add something to a webpage after the initial load. JavaScript gives us a variety of tools. Perhaps you’ve used some of them, like <code>append</code>, <code>appendChild</code>, <code>insertAdjacentHTML</code>, or <code>innerHTML</code>.</p>

<p>The difficult thing about appending and inserting things with JavaScript isn’t so much about the tools it offers, but which one to use, when to use them, and understanding how each one works.</p>

<p>Let’s try to clear things up.</p>

<h3 id="quick-context">Quick Context</h3>

<p><img src="/assets/images/blog/server.png" alt="" /></p>

<p>Your browser converts the HTML tags inside your HTML file into a bunch of objects that can be manipulated with JavaScript. These objects construct a <a href="https://developer.mozilla.org/en-US/docs/Glossary/DOM">Document Object Model</a> (DOM) tree. This tree is a series of objects that are structured as parent-child relationships.</p>

<p>In DOM parlance, these objects are called nodes, or more specifically, HTML elements.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- I'm the parent element --&gt;</span>
<span class="nt">&lt;div&gt;</span>
  <span class="c">&lt;!-- I'm a child element --&gt;</span>
  <span class="nt">&lt;span&gt;</span>Hello<span class="nt">&lt;/span&gt;</span>
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<p>In this example, the HTML span element is the child of the div element, which is the parent.</p>

<p>And I know that some of these terms are weird and possibly confusing. We say “node”, but other times we may say “element” or “object” instead. And, in some cases, they refer to the same thing, just depending on how specific we want to be .</p>

<p>For example, an “element” is a specific type of “node”, just like an apple is a specific type of fruit.</p>

<p>We can organize these terms from most general, to most specific: <a href="https://developer.mozilla.org/en-US/docs/Learn/JavaScript/Objects" target="_blank" rel="noreferrer noopener">Object</a> → <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node" target="_blank" rel="noreferrer noopener">Node</a> → <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element" target="_blank" rel="noreferrer noopener">Element</a> → <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement" target="_blank" rel="noreferrer noopener">HTML Element</a></p>

<p>Understanding these DOM items is important, as we’ll interact with them to add and append things with JavaScript after an initial page load. In fact, let’s start working on that.</p>

<h3 id="setup">Setup</h3>
<p>These append and insert methods mostly follow this pattern:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nx">Element</span><span class="p">.</span><span class="nf">append_method_choice</span><span class="p">(</span><span class="nx">stuff_to_append</span><span class="p">)</span>
</code></pre></div></div>

<p>Again, an <em>element</em> is merely an object in the DOM Tree that represents some HTML. Earlier, we had mentioned that the purpose of the DOM tree is to give us a convenient way to interact with HTML using JavaScript.</p>

<p>So, how do we use JavaScript to grab an HTML element?</p>

<h3 id="querying-the-dom">Querying the DOM</h3>

<p>Let’s say we have the following tiny bit of HTML:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"example"</span> <span class="na">class=</span><span class="s">"group"</span><span class="nt">&gt;</span>
  Hello World
<span class="nt">&lt;/div&gt;</span>
</code></pre></div></div>

<p>There are a few common ways to query the DOM:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Query a specific selector (could be class, ID, element type, or attribute):</span>
<span class="kd">const</span> <span class="nx">my_element1</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">#example</span><span class="dl">'</span><span class="p">)</span>

<span class="c1">// Query an element by its ID:</span>
<span class="kd">const</span> <span class="nx">my_element2</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementbyId</span><span class="p">(</span><span class="dl">'</span><span class="s1">example</span><span class="dl">'</span><span class="p">)</span>

<span class="c1">// Query an element by its class:</span>
<span class="kd">const</span> <span class="nx">my_element3</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">getElementbyClass</span><span class="p">(</span><span class="dl">'</span><span class="s1">group</span><span class="dl">'</span><span class="p">)[</span><span class="mi">0</span><span class="p">]</span>
</code></pre></div></div>

<p>In this example, all three lines query the same thing, but look for it in different ways. One looks at any of the item’s <a href="https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_Selectors" target="_blank">CSS selectors</a>; one looks at the item’s ID; and one looks at the item’s class.</p>

<p>Note that the <code>getElementbyClass</code> method returns an array. That’s because it’s capable of matching multiple elements in the DOM and storing those matches in an array makes sure all of them are accounted for.</p>

<h3 id="what-we-can-append-and-insert">What we can append and insert</h3>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c1">// Append Something</span>
<span class="kd">const</span> <span class="nx">my_element1</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">#example</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">my_element1</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">something</span><span class="p">)</span>
</code></pre></div></div>

<p>In this example, <em>something</em> is a parameter that represents stuff we want to tack on to the end of (i.e. append to) the matched element.</p>

<p>We can’t just append any old thing to any old object. The append method only allows us to append either a node or plain text to an element in the DOM. But some other methods can append HTML to DOM elements as well.</p>

<ol>
  <li>
    <p>Nodes are either created with <code class="language-plaintext highlighter-rouge">document.createElement()</code> in JavaScript, or they are selected with one of the query methods we looked at in the last section.</p>
  </li>
  <li>
    <p>Plain text is, well, text. It’s plain text in that it does not carry any HTML tags or formatting with it. (e.g. Hello).</p>
  </li>
  <li>
    <p>HTML is also text but, unlike plain text, it does indeed get parsed as markup when it’s added to the DOM (e.g. <code class="language-plaintext highlighter-rouge">&lt;div&gt;Hello&lt;/div&gt;</code>).</p>
  </li>
</ol>

<p>It might help to map out exactly which parameters are supported by which methods:</p>
<div class="table-section">
<table><thead><tr><th>Method</th><th>Node</th><th>HTML Text</th><th>Text</th></tr></thead><tbody><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Element/append" rel="noreferrer noopener"><code>append</code></a></td><td>Yes</td><td>No</td><td>Yes</td></tr><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild" rel="noreferrer noopener"><code>appendChild</code></a></td><td>Yes</td><td>No</td><td>No</td></tr><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML" rel="noreferrer noopener"><code>insertAdjacentHTML</code></a></td><td>No</td><td>Yes</td><td>Yes<sup>1</sup></td></tr><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML" rel="noreferrer noopener"><code>innerHTML</code><sup>2</sup></a></td><td>No</td><td>Yes</td><td>Yes</td></tr></tbody></table>
<p class="super">
<sup>1</sup> This works, but <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText" target="_blank" rel="noreferrer noopener">insertAdjacentText</a></code> is recommended.<br /><sup>2</sup> Instead of taking traditional parameters, <code>innerHTML</code> is used like: <code>element.innerHTML = 'HTML String'</code>
</p>
</div>

<h3 id="how-to-choose-which-method-to-use">How to choose which method to use</h3>

<p>Well, it really depends on what you’re looking to append, not to mention certain browser quirks to work around.</p>

<ul>

<li>If you have existing HTML that gets sent to your JavaScript, it's probably easiest to work with methods that support HTML.</li>

<li>If you're building some new HTML in JavasScript, creating a node with heavy markup can be cumbersome, whereas HTML is less verbose.</li>

<li>If you want to attach event listeners right away, you'll want to work with nodes because we call <code><a href="https://developer.mozilla.org/en-US/docs/Web/API/EventTarget/addEventListener" target="_blank">addEventListener</a></code> on nodes, not HTML.</li>

<li>If all you need is text, any method supporting plain text parameters is fine.</li>

<li>If your HTML is <a href="https://en.wikipedia.org/wiki/Cross-site_scripting" target="_blank">potentially untrustworthy</a> (i.e. it comes from user input, say a comment on a blog post), then you’ll want to be careful when using HTML, unless it has been sanitized (i.e. the harmful code has been removed).</li>

<li>If you need to support Internet Explorer, then <a href="https://caniuse.com/mdn-api_element_append" target="_blank">using <code>append</code> is out of the question</a>.</li>

</ul>

<h3 id="example">Example</h3>

<p>Let’s say we have a chat application, and we want to append a user, Dale, to a buddy list when they log in.</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- HTML Buddy List --&gt;</span>
<span class="nt">&lt;ul</span> <span class="na">id=</span><span class="s">"buddies"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;li&gt;&lt;a&gt;</span>Alex<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
  <span class="nt">&lt;li&gt;&lt;a&gt;</span>Barry<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
  <span class="nt">&lt;li&gt;&lt;a&gt;</span>Clive<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
  <span class="c">&lt;!-- Append next user here --&gt;</span>
<span class="nt">&lt;/ul&gt;</span>
</code></pre></div></div>

<p>Here’s how we’d accomplish this using each of the methods above.</p>

<h3 id="append"><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/append">append</a></h3>

<p>We need to create a node object that translates to <code class="language-plaintext highlighter-rouge">&lt;li&gt;&lt;a&gt;Dale&lt;/a&gt;&lt;/li&gt;</code>.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">new_buddy</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">li</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">new_link</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">)</span>

<span class="kd">const</span> <span class="nx">buddy_name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Dale</span><span class="dl">"</span>

<span class="nx">new_link</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">buddy_name</span><span class="p">)</span> <span class="c1">// Text param</span>
<span class="nx">new_buddy</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">new_link</span><span class="p">)</span> <span class="c1">// Node param</span>

<span class="kd">const</span> <span class="nx">list</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">#buddies</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">list</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">new_buddy</span><span class="p">)</span> <span class="c1">// Node param</span>
</code></pre></div></div>

<p>Our final append places the new user at the end of the buddy list, just before the closing <code class="language-plaintext highlighter-rouge">&lt;/ul&gt;</code> tag. If we’d prefer to place the user at the front of the list, we could use the <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/prepend">prepend</a> method instead.</p>

<p>You may have noticed that we were also able to use append to fill our <code class="language-plaintext highlighter-rouge">&lt;a&gt;</code> tag with text like this:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">buddy_name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Dale</span><span class="dl">"</span>
<span class="nx">new_link</span><span class="p">.</span><span class="nf">append</span><span class="p">(</span><span class="nx">buddy_name</span><span class="p">)</span> <span class="c1">// Text param</span>
</code></pre></div></div>

<p>This highlights the versatility of append.</p>

<p>And just to call it out once more, <code class="language-plaintext highlighter-rouge">append</code> is <a href="https://caniuse.com/mdn-api_element_append">unsupported in Internet Explorer</a>.</p>

<h3 id="appendchild"><a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild">appendChild</a></h3>

<p><code class="language-plaintext highlighter-rouge">appendChild</code> is another JavaScript method we have for appending stuff to DOM elements. It’s a little limited in that it only works with node objects, so we we’ll need some help from <a href="https://developer.mozilla.org/en-US/docs/Web/API/Node/textContent">textContent</a> (or <a href="https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/innerText">innerText</a>) for our plain text needs.</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">new_buddy</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">li</span><span class="dl">'</span><span class="p">)</span>
<span class="kd">const</span> <span class="nx">new_link</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">)</span>

<span class="kd">const</span> <span class="nx">buddy_name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Dale</span><span class="dl">"</span>

<span class="nx">new_link</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="nx">buddy_name</span>
<span class="nx">new_buddy</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">new_link</span><span class="p">)</span> <span class="c1">// Node param</span>

<span class="kd">const</span> <span class="nx">list</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">#buddies</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">list</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">new_buddy</span><span class="p">)</span> <span class="c1">// Node param</span>
</code></pre></div></div>

<p>Note that <code class="language-plaintext highlighter-rouge">appendChild</code>, unlike append, <a href="https://caniuse.com/mdn-api_node_appendchild">is supported in Internet Explorer</a>.</p>

<p>Before moving on, let’s consider a similar example, but with heavier markup.</p>

<p>Let’s say the HTML we wanted to append didn’t look like <code class="language-plaintext highlighter-rouge">&lt;li&gt;&lt;a&gt;Dale&lt;/a&gt;&lt;/li&gt;</code>, but rather:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;li</span> <span class="na">class=</span><span class="s">"abc"</span> <span class="na">data-tooltip=</span><span class="s">"Click for Dale"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;a</span> <span class="na">id=</span><span class="s">"user_123"</span> <span class="na">class=</span><span class="s">"def"</span> <span class="na">data-user=</span><span class="s">"dale"</span><span class="nt">&gt;</span>
    <span class="nt">&lt;img</span> <span class="na">src=</span><span class="s">"images/dale.jpg"</span> <span class="na">alt=</span><span class="s">"Profile Picture"</span><span class="nt">/&gt;</span>
    <span class="nt">&lt;span&gt;</span>Dale<span class="nt">&lt;/span&gt;</span>
  <span class="nt">&lt;/a&gt;</span>
<span class="nt">&lt;/li&gt;</span>
</code></pre></div></div>

<p>Our JavaScript would look something like:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">buddy_name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Dale</span><span class="dl">"</span>

<span class="kd">const</span> <span class="nx">new_buddy</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">li</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">new_buddy</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="p">(</span><span class="dl">'</span><span class="s1">abc</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">new_buddy</span><span class="p">.</span><span class="nf">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-tooltip</span><span class="dl">'</span><span class="p">,</span> <span class="s2">`Click for </span><span class="p">${</span><span class="nx">buddy_name</span><span class="p">}</span><span class="s2">`</span><span class="p">)</span>

<span class="kd">const</span> <span class="nx">new_link</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">a</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">new_link</span><span class="p">.</span><span class="nx">id</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">user_123</span><span class="dl">'</span>
<span class="nx">new_link</span><span class="p">.</span><span class="nx">className</span> <span class="o">=</span> <span class="p">(</span><span class="dl">'</span><span class="s1">def</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">new_link</span><span class="p">.</span><span class="nf">setAttribute</span><span class="p">(</span><span class="dl">'</span><span class="s1">data-user</span><span class="dl">'</span><span class="p">,</span> <span class="nx">buddy_name</span><span class="p">)</span>

<span class="kd">const</span> <span class="nx">new_profile_img</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">img</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">new_profile_img</span><span class="p">.</span><span class="nx">src</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">images/dale.jpg</span><span class="dl">'</span>
<span class="nx">new_profile_img</span><span class="p">.</span><span class="nx">alt</span> <span class="o">=</span> <span class="dl">'</span><span class="s1">Profile Picture</span><span class="dl">'</span>

<span class="kd">const</span> <span class="nx">new_buddy_span</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">createElement</span><span class="p">(</span><span class="dl">'</span><span class="s1">span</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">new_buddy_span</span><span class="p">.</span><span class="nx">textContent</span> <span class="o">=</span> <span class="nx">buddy_name</span>

<span class="nx">new_link</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">new_profile_img</span><span class="p">)</span> <span class="c1">// Node param</span>
<span class="nx">new_link</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">new_buddy_span</span><span class="p">)</span> <span class="c1">// Node param</span>
<span class="nx">new_buddy</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">new_link</span><span class="p">)</span> <span class="c1">// Node param</span>

<span class="kd">const</span> <span class="nx">list</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">#buddies</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">list</span><span class="p">.</span><span class="nf">appendChild</span><span class="p">(</span><span class="nx">new_buddy</span><span class="p">)</span> <span class="c1">// Node param</span>
</code></pre></div></div>

<p>There’s no need to follow all of above JavaScript – the point is that creating large amounts of HTML in JavaScript can become quite cumbersome. And there’s no getting around this if we use <code class="language-plaintext highlighter-rouge">append</code> or <code class="language-plaintext highlighter-rouge">appendChild</code>.</p>

<p>In this heavy markup scenario, it might be nice to just write our HTML as a string, rather than using a bunch of JavaScript methods…</p>

<h3 id="insertadjacenthtml"><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML">insertAdjacentHTML</a></h3>

<p><code class="language-plaintext highlighter-rouge">insertAdjacentHTML</code> is is like <code class="language-plaintext highlighter-rouge">append</code> in that it’s also capable of adding stuff to DOM elements. One difference, though, is that <code class="language-plaintext highlighter-rouge">insertAdjacentHTML</code> inserts that stuff at a specific position relative to the matched element.</p>

<p>And it just so happens to work with HTML. That means we can insert actual HTML to a DOM element, and pinpoint exactly where we want it with four different positions:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="c">&lt;!-- beforebegin --&gt;</span>
<span class="nt">&lt;div</span> <span class="na">id=</span><span class="s">"example"</span> <span class="na">class=</span><span class="s">"group"</span><span class="nt">&gt;</span>
  <span class="c">&lt;!-- afterbegin --&gt;</span>
  Hello World
  <span class="c">&lt;!-- beforeend --&gt;</span>
<span class="nt">&lt;/div&gt;</span>
<span class="c">&lt;!-- afterend --&gt;</span>
</code></pre></div></div>

<p>So, we can sorta replicate the same idea of “appending” our HTML by inserting it at the <code class="language-plaintext highlighter-rouge">beforeend</code> position of the <code class="language-plaintext highlighter-rouge">#buddies</code> selector:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">buddy_name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Dale</span><span class="dl">"</span>

<span class="kd">const</span> <span class="nx">new_buddy</span> <span class="o">=</span> <span class="s2">`&lt;li&gt;&lt;a&gt;</span><span class="p">${</span><span class="nx">buddy_name</span><span class="p">}</span><span class="s2">&lt;/a&gt;&lt;/li&gt;`</span>
<span class="kd">const</span> <span class="nx">list</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">#buddies</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">list</span><span class="p">.</span><span class="nf">insertAdjacentHTML</span><span class="p">(</span><span class="dl">'</span><span class="s1">beforeend</span><span class="dl">'</span><span class="p">,</span> <span class="nx">new_buddy</span><span class="p">)</span>
</code></pre></div></div>

<p>Remember the security concerns we mentioned earlier. We never want to insert HTML that’s been submitted by an end user, as we’d open ourselves up to <a href="https://en.wikipedia.org/wiki/Cross-site_scripting">cross-site scripting</a> vulnerabilities.</p>

<h3 id="innerhtml"><a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML">innerHTML</a></h3>

<p><code class="language-plaintext highlighter-rouge">innerHTML</code> is another method for inserting stuff. That said, it’s not recommended for inserting, as we’ll see.</p>

<p>Here’s our query and the HTML we want to insert:</p>

<div class="language-javascript highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="kd">const</span> <span class="nx">buddy_name</span> <span class="o">=</span> <span class="dl">"</span><span class="s2">Dale</span><span class="dl">"</span>
<span class="kd">const</span> <span class="nx">new_buddy</span> <span class="o">=</span> <span class="s2">`&lt;li&gt;&lt;a&gt;</span><span class="p">${</span><span class="nx">buddy_name</span><span class="p">}</span><span class="s2">&lt;/a&gt;&lt;/li&gt;`</span>
<span class="kd">const</span> <span class="nx">list</span> <span class="o">=</span> <span class="nb">document</span><span class="p">.</span><span class="nf">querySelector</span><span class="p">(</span><span class="dl">'</span><span class="s1">#buddies</span><span class="dl">'</span><span class="p">)</span>
<span class="nx">list</span><span class="p">.</span><span class="nx">innerHTML</span> <span class="o">+=</span> <span class="nx">new_buddy</span>
</code></pre></div></div>

<p>Initially, this seems to work. Our updated buddy list looks like this in the DOM:</p>

<div class="language-html highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="nt">&lt;ul</span> <span class="na">id=</span><span class="s">"buddies"</span><span class="nt">&gt;</span>
  <span class="nt">&lt;li&gt;&lt;a&gt;</span>Alex<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
  <span class="nt">&lt;li&gt;&lt;a&gt;</span>Barry<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
  <span class="nt">&lt;li&gt;&lt;a&gt;</span>Clive<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
  <span class="nt">&lt;li&gt;&lt;a&gt;</span>Dale<span class="nt">&lt;/a&gt;&lt;/li&gt;</span>
<span class="nt">&lt;/ul&gt;</span>
</code></pre></div></div>

<p>That’s what we want! But there’s a constraint with using <code class="language-plaintext highlighter-rouge">innerHTML</code> that prevents us from using event listeners on any element inside of #buddies because of the nature of <code class="language-plaintext highlighter-rouge">+=</code> in <code class="language-plaintext highlighter-rouge">list.innerHTML += new_buddy</code>.</p>

<p>You see, A += B behaves the same as A = A + B. In this case, A is our existing HTML and B is what we’re inserting to it. The problem is that this results in a copy of the existing HTML with the additional inserted HTML. And event listeners are unable to listen to copies. That means if we want to listen for a click event on any of the <code class="language-plaintext highlighter-rouge">&lt;a&gt;</code> tags in the buddy list, we’re going to lose that ability with <code class="language-plaintext highlighter-rouge">innerHTML</code>.</p>

<p>So, just a word of caution there.</p>

<h3 id="demo">Demo</h3>

<p>Here’s a demo that pulls together all of the methods we’ve covered. Clicking the button of each method inserts “Dale” as an item in the buddies list.</p>

<div class="wp-block-cp-codepen-gutenberg-embed-block cp_embed_wrapper"><iframe id="cp_embed_eYRdOvg" src="//codepen.io/anon/embed/eYRdOvg?height=450&amp;theme-id=1&amp;slug-hash=eYRdOvg&amp;default-tab=result" height="450" scrolling="no" frameborder="0" allowfullscreen="" allowpaymentrequest="" name="CodePen Embed eYRdOvg" title="CodePen Embed eYRdOvg" class="cp_embed_iframe" style="width:100%;overflow:hidden">CodePen Embed Fallback</iframe></div>

<h3 id="recap">Recap</h3>

<p>Here’s a general overview of where we stand when we’re appending and inserting stuff into the DOM. Consider it a cheatsheet for when you need help figuring out which method to use.</p>
<div class="table-section">
<table><thead><tr><th>Method</th><th>Node<br /></th><th>HTML</th><th>Text<br /></th><th>IE?</th><th>Events?</th><th>Secure?<br /></th><th>HTML Templating</th></tr></thead><tbody><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Element/append" rel="noreferrer noopener"><code>append</code></a></td><td>Yes</td><td>No</td><td>Yes</td><td>No</td><td>Preserves</td><td>Yes</td><td>Medium</td></tr><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Node/appendChild" rel="noreferrer noopener"><code>appendChild</code></a></td><td>Yes</td><td>No</td><td>No</td><td>Yes</td><td>Preserves</td><td>Yes</td><td>Medium</td></tr><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentHTML" rel="noreferrer noopener"><code>insertAdjacentHTML</code></a></td><td>No</td><td>Yes</td><td>Yes<sup>1</sup></td><td>Yes</td><td>Preserves</td><td>Careful</td><td>Easy</td></tr><tr><td><a target="_blank" href="https://developer.mozilla.org/en-US/docs/Web/API/Element/innerHTML" rel="noreferrer noopener"><code>innerHTML</code></a><sup>2</sup></td><td>No</td><td>Yes</td><td>Yes</td><td>Yes</td><td>Loses</td><td>Careful</td><td>Easy</td></tr></tbody></table>

<p class="super">
<sup>1</sup> This works, but <code>insertAdjacentText</code> is <a href="https://developer.mozilla.org/en-US/docs/Web/API/Element/insertAdjacentText" target="_blank" rel="noreferrer noopener">recommended</a>.<br /><sup>2</sup> Instead of taking traditional parameters, <code>innerHTML</code> is used like: <code>element.innerHTML = 'HTML String'</code>
</p>
</div>

<p>If I had to condense all of that into a few recommendations:</p>

<ul>
  <li>
    <p>Using <code class="language-plaintext highlighter-rouge">innerHTML</code> for appending is not recommended as it removes event listeners.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">append</code> works well if you like the flexibility of working with node elements or plain text, and don’t need to support Internet Explorer.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">appendChild</code> works well if you like (or need) to work with node elements, and want full browser coverage.</p>
  </li>
  <li>
    <p><code class="language-plaintext highlighter-rouge">insertAdjacentHTML</code> is nice if you need to generate HTML, and want to more specific control over where it is placed in the DOM.</p>
  </li>
</ul>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[This post also lives over at CSS Tricks]]></summary></entry><entry><title type="html">How to get banned from SendGrid in 10 seconds</title><link href="https://unfoundedlabs.com/blog/sendgrid-ban" rel="alternate" type="text/html" title="How to get banned from SendGrid in 10 seconds" /><published>2020-11-29T00:00:00+00:00</published><updated>2020-11-29T00:00:00+00:00</updated><id>https://unfoundedlabs.com/blog/sendgrid-banned</id><content type="html" xml:base="https://unfoundedlabs.com/blog/sendgrid-ban"><![CDATA[<h3 id="be-careful-what-you-tell-your-computers-to-do-because-theyll-do-it">Be Careful what you tell your computers to do, because they’ll do it.</h3>

<p>I’m making a web app using Rails, and the gem <a href="https://github.com/faker-ruby/faker">Faker</a> allows us to work with dummy user data before actual non-dummies Log On.</p>

<p>I was using the Harry Potter flavor of Faker’s dummy data, so my users had names like Fluffle BippleBap and emails like fbibblebap@gmail.com.</p>

<p>When a user creates an account, she gets a welcome email. Rails ActionMailer makes this nice and easy.</p>

<p>Since we’re in Rails Land, of course we’re using Devise - this allows us to create and manage user accounts with ease.</p>

<h3 id="controllers-and-models">Controllers and Models</h3>

<p>Since we’ve outsourced our account creation to Devise, we don’t have immediate access to a <code class="language-plaintext highlighter-rouge">create</code> action in the <code class="language-plaintext highlighter-rouge">users_controller</code> - Devise has it’s own controllers.</p>

<p>But we want to send a user an email after her account is created - seems like this could live happily in the <code class="language-plaintext highlighter-rouge">create</code> action that we don’t have.</p>

<p>So we seem to have at least 2 options.</p>

<ol>
  <li>We can extend the Devise <code class="language-plaintext highlighter-rouge">registrations_controller</code> and add an <code class="language-plaintext highlighter-rouge">after_action</code> to the <code class="language-plaintext highlighter-rouge">create</code> action that sends a welcome email. I probably should have done this.</li>
  <li>We can add an <code class="language-plaintext highlighter-rouge">after_create</code> callback in the <code class="language-plaintext highlighter-rouge">User</code> model that sends the email. Needless to say, this is what I did.</li>
</ol>

<p>Now this toxic seed was planted weeks before it grew into a full banning from SendGrid, thanks in part to another handy Rails gem called <a href="https://github.com/ryanb/letter_opener">Letter Opener</a>.</p>

<p>Instead of sending an actual email to fbipplebap@gmail.com, Letter Opener just shows us a pretend HTML email in our browser.</p>

<h3 id="the-main-event">The Main Event</h3>

<p>So we’re using Letter Opener in our development environment, but not for our staging environment, because in staging, we want to see that emails actually get delivered.</p>

<p>Now you can probably see where this is headed. Here are the magical 10 seconds that led to my banning:</p>

<p>On my Heroku dashboard for the staging site, I added the SendGrid add-on. <em>(3 seconds)</em></p>

<p>Then, I seeded the staging database: <code class="language-plaintext highlighter-rouge">rails db:seed</code> . <em>(3 seconds)</em></p>

<p>Then, 100 Harry Potter dummies were created. The <code class="language-plaintext highlighter-rouge">after_create</code> callback mentioned above is fired 100 times, and 100 emails are sent to Harry Potters. And 100 emails bounce. <em>(4 seconds)</em></p>

<p>I set up my computer to fail. And SendGrid’s computer is smart enough to notice my 100% bounce rate, and promptly banned me.</p>

<h3 id="a-better-approach">A Better Approach</h3>

<p>Instead of the <code class="language-plaintext highlighter-rouge">after_create</code> callback on the model, I could have extended the Devise controller, and used an <code class="language-plaintext highlighter-rouge">after_action</code> .</p>

<p>The difference between these two approaches may seem minor, but the difference between being banned and not being banned is major.</p>

<p>The <code class="language-plaintext highlighter-rouge">after_create</code> method will fire any time a record is created for the corresponding model - i.e. <code class="language-plaintext highlighter-rouge">User.create</code> This could happen from the console, the seed file, or from inside a controller somewhere. My self-inflicted damage happened in the seed file.</p>

<p>If I had used an <code class="language-plaintext highlighter-rouge">after_action</code> in a controller, I would have been safe. This is because the controller action is only called from a specific route - when the user actually interacts with the UI. The controller action is unrelated to me calling <code class="language-plaintext highlighter-rouge">User.create</code> somewhere else in my code.</p>

<h3 id="another-approach">Another Approach</h3>

<p>Use real emails! This was actually my first fix. I created an alias email in the Google Apps admin (t@bouncerip.com)  that gets forwarded and skips the inbox. And in the seed file, just used something that looked like this:</p>

<div class="language-ruby highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="mi">100</span><span class="p">.</span><span class="nf">times</span> <span class="k">do</span> <span class="o">|</span><span class="n">i</span><span class="o">|</span>
	<span class="n">u</span> <span class="o">=</span> <span class="no">User</span><span class="p">.</span><span class="nf">new</span>
	<span class="n">u</span><span class="p">.</span><span class="nf">email</span> <span class="o">=</span> <span class="s2">"t+</span><span class="si">#{</span><span class="n">i</span><span class="si">}</span><span class="s2">@bouncerip.com"</span>
	<span class="n">u</span><span class="p">.</span><span class="nf">save</span>
<span class="k">end</span>
</code></pre></div></div>

<h3 id="post-morten">Post Morten</h3>

<p>SendGrid, please unban me!</p>]]></content><author><name></name></author><category term="blog" /><summary type="html"><![CDATA[Be Careful what you tell your computers to do, because they’ll do it.]]></summary></entry></feed>