<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>TIL on Jake Worth</title><link>https://jakeworth.com/tils/</link><description>Recent content in TIL on Jake Worth</description><image><title>Jake Worth</title><url>https://jakeworth.com/twittercard.png</url><link>https://jakeworth.com/twittercard.png</link></image><generator>Hugo</generator><language>en-us</language><lastBuildDate>Fri, 24 Jul 2026 10:56:14 -0400</lastBuildDate><atom:link href="https://jakeworth.com/tils/index.xml" rel="self" type="application/rss+xml"/><item><title>tsx, a REPL for TypeScript</title><link>https://jakeworth.com/tils/tsx-a-repl-for-typescript/</link><pubDate>Fri, 24 Jul 2026 10:56:14 -0400</pubDate><guid>https://jakeworth.com/tils/tsx-a-repl-for-typescript/</guid><description>&lt;p&gt;Today I discovered &lt;code&gt;tsx&lt;/code&gt;, a REPL that evalutes TypeScript. You can run it with
npx:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npx tsx
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And it evaluates TypeScript.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onClick&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;input&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;number&lt;/span&gt;)&lt;span style="color:#f92672"&gt;:&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;void&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;input&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onClick&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Enumerate on promise resolved</title><link>https://jakeworth.com/tils/enumerate-on-promised-resolved/</link><pubDate>Fri, 24 Jul 2026 09:45:07 -0400</pubDate><guid>https://jakeworth.com/tils/enumerate-on-promised-resolved/</guid><description>&lt;p&gt;For the golfers out there, we can combine these two lines into one:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;items&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getCollection&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;items&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;();
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This doesn&amp;rsquo;t work because &lt;code&gt;sort()&lt;/code&gt; is being called on the promise returned by
&lt;code&gt;getCollection()&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getCollection&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// `sort()` runs on the Promise
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Instead, wrap the &lt;code&gt;await&lt;/code&gt; expression in parentheses so &lt;code&gt;sort()&lt;/code&gt; is called on the
resolved value:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;await&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getCollection&lt;/span&gt;()).&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(); &lt;span style="color:#75715e"&gt;// `sort()` runs on the resolved array
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;ul&gt;
&lt;li&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Promise"&gt;Promise documentation&lt;/a&gt; -
MDN&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>4321 is Astro</title><link>https://jakeworth.com/tils/4321-is-astro/</link><pubDate>Tue, 21 Jul 2026 12:51:02 -0400</pubDate><guid>https://jakeworth.com/tils/4321-is-astro/</guid><description>&lt;p&gt;Astro&amp;rsquo;s default port is 4321. Like &lt;a href="https://jakeworth.com/tils/5173-is-vite"&gt;Vite&lt;/a&gt;, this project is
trying to convey its (rocket-launch) branding, even in this small detail.&lt;/p&gt;</description></item><item><title>Node's Timeout _destroyed Private Method</title><link>https://jakeworth.com/tils/nodes-destroyed-private-method/</link><pubDate>Mon, 20 Jul 2026 16:44:20 -0400</pubDate><guid>https://jakeworth.com/tils/nodes-destroyed-private-method/</guid><description>&lt;p&gt;Node &lt;code&gt;Timeout&lt;/code&gt; timers have a private boolean attribute called &lt;code&gt;_destroyed&lt;/code&gt;. It
tells you if the function has been cleared:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;timer&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;_destroyed&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Uncheck Buttons With JavaScript</title><link>https://jakeworth.com/tils/uncheck-buttons-with-javascript/</link><pubDate>Mon, 20 Jul 2026 09:21:10 -0400</pubDate><guid>https://jakeworth.com/tils/uncheck-buttons-with-javascript/</guid><description>&lt;p&gt;Today I used JavaScript to mass-unsubscribe from a website&amp;rsquo;s email
notifications. Here&amp;rsquo;s the code, followed by what I did and why.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;document
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;querySelectorAll&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;[role=&amp;#34;switch&amp;#34;]&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; .&lt;span style="color:#a6e22e"&gt;forEach&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;element&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;click&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>JavaScript Reflection with toString</title><link>https://jakeworth.com/tils/js-reflection-with-to-string/</link><pubDate>Fri, 10 Jul 2026 12:04:19 -0400</pubDate><guid>https://jakeworth.com/tils/js-reflection-with-to-string/</guid><description>&lt;p&gt;&lt;em&gt;Reflection&lt;/em&gt; is an important tool in programming; it lets us examine a
language&amp;rsquo;s structure. Can we reflect in JavaScript? Sort of.&lt;/p&gt;
&lt;p&gt;Some functions can be reflected with &lt;code&gt;toString()&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;one&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () =&amp;gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;one&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;() =&amp;gt; 1&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Very cool! But native functions only return this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; Math.&lt;span style="color:#a6e22e"&gt;max&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;toString&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;function max() { [native code] }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You must read the ECMA Script specification to know what the function is
required to do. The actual implementation is written in the JavaScript engine,
likely in another language like C++, which is why Node can&amp;rsquo;t show it via
&lt;code&gt;toString()&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Focus a JS Test</title><link>https://jakeworth.com/tils/focus-a-js-test/</link><pubDate>Fri, 10 Jul 2026 11:48:47 -0400</pubDate><guid>https://jakeworth.com/tils/focus-a-js-test/</guid><description>&lt;p&gt;A vital testing skill is &lt;em&gt;focusing&lt;/em&gt; a test. When iterating on a failing test, we
want that test under microscope.&lt;/p&gt;
&lt;p&gt;The way I do this in JavaScript is &lt;code&gt;.only&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;describe&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;expect&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;vitest&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./sum.js&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;adds 1 + 2 to equal 3&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;expect&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)).&lt;span style="color:#a6e22e"&gt;toBe&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;describe&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;only&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;adding fours&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;test&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;adds 4 + 4 to equal 8&amp;#39;&lt;/span&gt;, () =&amp;gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;expect&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;sum&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;4&lt;/span&gt;)).&lt;span style="color:#a6e22e"&gt;toBe&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;8&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; });
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>JSDoc Deprecations in TypeScript</title><link>https://jakeworth.com/tils/js-doc-deprecations-in-typescript/</link><pubDate>Fri, 10 Jul 2026 10:35:05 -0400</pubDate><guid>https://jakeworth.com/tils/js-doc-deprecations-in-typescript/</guid><description>&lt;p&gt;JSDoc has a &lt;code&gt;@deprecated&lt;/code&gt; tag that you can use in TypeScript, too. Here&amp;rsquo;s an
example.&lt;/p&gt;</description></item><item><title>Unknown Value in Brackets</title><link>https://jakeworth.com/tils/unknown-value-in-brackets/</link><pubDate>Tue, 07 Jul 2026 12:05:47 -0400</pubDate><guid>https://jakeworth.com/tils/unknown-value-in-brackets/</guid><description>&lt;p&gt;I&amp;rsquo;m reading &lt;a href="https://howtoopensource.dev/"&gt;&lt;em&gt;How to Open Source&lt;/em&gt;&lt;/a&gt; by Richard
Schneeman (fantastic) and one of his tips is to show documentation code like
this (consider documenting &lt;code&gt;ls&lt;/code&gt;):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ls &amp;lt;desired-path&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Rather than the common:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ls /your/path/here
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>NPM List Packages</title><link>https://jakeworth.com/tils/npm-list-packages/</link><pubDate>Tue, 07 Jul 2026 10:00:34 -0400</pubDate><guid>https://jakeworth.com/tils/npm-list-packages/</guid><description>&lt;p&gt;When upgrading a dependency for a security issue, we might upgrade and move on:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm install &amp;lt;dependency&amp;gt;@&amp;lt;version&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But wait! Was every &lt;code&gt;&amp;lt;dependency&amp;gt;&lt;/code&gt; version upgraded, or just the version in
&lt;code&gt;package.json&lt;/code&gt;? Check with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;npm list // or npm ls
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Rust Erroring Code Visual Aid</title><link>https://jakeworth.com/tils/rust-erroring-code-visual-aid/</link><pubDate>Mon, 06 Jul 2026 11:16:08 -0400</pubDate><guid>https://jakeworth.com/tils/rust-erroring-code-visual-aid/</guid><description>&lt;p&gt;Today while reading the &lt;a href="https://doc.rust-lang.org/"&gt;Rust Documentation&lt;/a&gt;, I
encountered a fantastic UX touch. The authors provide this image with each code
block that intentionally doesn&amp;rsquo;t compile:&lt;/p&gt;
&lt;figure&gt;
&lt;img loading="lazy" src="https://doc.rust-lang.org/book/img/ferris/does_not_compile.svg"
alt="Doesn&amp;#39;t Compile" width="300"/&gt;
&lt;/figure&gt;</description></item><item><title>Resized Images in Hugo Markdown</title><link>https://jakeworth.com/tils/resized-images-in-hugo-markdown/</link><pubDate>Thu, 02 Jul 2026 15:22:48 -0400</pubDate><guid>https://jakeworth.com/tils/resized-images-in-hugo-markdown/</guid><description>&lt;p&gt;Images in Hugo can be a bit tricky. Here&amp;rsquo;s how I&amp;rsquo;ve added images on my projects
page that are resized, linked, and have alts: the &lt;code&gt;figure&lt;/code&gt; shortcode.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go-html-template" data-lang="go-html-template"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;{{&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;figure&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;src&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/images/yiap.png&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;alt&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;Yes, It&amp;#39;s a Problem&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;link&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://github.com/jwworth/yes-its-a-problem&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;width&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;600&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;gt;&lt;/span&gt;&lt;span style="color:#75715e"&gt;}}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Unalias an Alias</title><link>https://jakeworth.com/tils/unalias-an-alias/</link><pubDate>Wed, 01 Jul 2026 11:45:19 -0400</pubDate><guid>https://jakeworth.com/tils/unalias-an-alias/</guid><description>&lt;p&gt;Sometimes I want to iterate on an alias. You can unalias an alias like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;unalias aliasname
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Vim Scriptout and Scriptin</title><link>https://jakeworth.com/tils/vim-scriptout-and-scriptin/</link><pubDate>Tue, 30 Jun 2026 15:17:23 -0400</pubDate><guid>https://jakeworth.com/tils/vim-scriptout-and-scriptin/</guid><description>&lt;p&gt;Today I discovered these two Vim flags:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;vim -w log.txt file
vim -s log.txt file
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;-w&lt;/code&gt; flag sends all keystrokes in your session to &lt;code&gt;log.txt&lt;/code&gt;. The &lt;code&gt;-s&lt;/code&gt; loads
Vim and replays all the keystroke back onto that file.&lt;/p&gt;</description></item><item><title>Concatenate Non-Printing Characters</title><link>https://jakeworth.com/tils/cat-non-printing-characters/</link><pubDate>Tue, 30 Jun 2026 12:29:45 -0400</pubDate><guid>https://jakeworth.com/tils/cat-non-printing-characters/</guid><description>&lt;p&gt;I&amp;rsquo;ve been writing some non-printing characters to a file. But when I
concatenate, it appears empty.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat log.txt
# Nothing here 🥺
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;cat&lt;/code&gt; those non-printing characters with &lt;code&gt;-v&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cat -v log.txt
jjjj:wq^M%
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Vite Hot Module Replacement</title><link>https://jakeworth.com/tils/vite-hot-module-replacement/</link><pubDate>Tue, 30 Jun 2026 09:33:35 -0400</pubDate><guid>https://jakeworth.com/tils/vite-hot-module-replacement/</guid><description>&lt;p&gt;I was doing a Vite demo last week, I changed some markup, and visited the local
web server. The markup changed, but the state persisted. What?!&lt;/p&gt;
&lt;p&gt;This is Vite&amp;rsquo;s Hot Module Replacement API.&lt;/p&gt;</description></item><item><title>Prettier in Fenced Code Blocks</title><link>https://jakeworth.com/tils/prettier-in-fenced-code-blocks/</link><pubDate>Mon, 29 Jun 2026 14:06:11 -0400</pubDate><guid>https://jakeworth.com/tils/prettier-in-fenced-code-blocks/</guid><description>&lt;p&gt;Prettier formats code in fenced code blocks! When I type three backticks and
then a code block, Prettier evaluates the code in the block and tries to format
it per my global &lt;code&gt;.prettierrc&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>TypeScript Type-Only Imports and Exports</title><link>https://jakeworth.com/tils/typescript-type-only-imports-and-exports/</link><pubDate>Mon, 29 Jun 2026 13:49:24 -0400</pubDate><guid>https://jakeworth.com/tils/typescript-type-only-imports-and-exports/</guid><description>&lt;p&gt;If you&amp;rsquo;ve been writing TypeScript for a while, you might have written code like
this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// utils.ts
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;export&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Color&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;red&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;blue&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;green&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// app.tsx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;Color&lt;/span&gt;} &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./utils&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;As of TypeScript 3.8, there&amp;rsquo;s a better way to import!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// app.tsx
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;import&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; {&lt;span style="color:#a6e22e"&gt;Color&lt;/span&gt;} &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;./utils&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Non-Null With Root Import</title><link>https://jakeworth.com/tils/non-null-with-root-import/</link><pubDate>Mon, 29 Jun 2026 11:24:16 -0400</pubDate><guid>https://jakeworth.com/tils/non-null-with-root-import/</guid><description>&lt;p&gt;New Vite TypeScript/React apps create themselves like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;createRoot&lt;/span&gt;(document.&lt;span style="color:#a6e22e"&gt;getElementById&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;root&amp;#39;&lt;/span&gt;)&lt;span style="color:#f92672"&gt;!&lt;/span&gt;).&lt;span style="color:#a6e22e"&gt;render&lt;/span&gt;(&amp;lt;&lt;span style="color:#f92672"&gt;App&lt;/span&gt; /&amp;gt;);
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;What&amp;rsquo;s going on with that &lt;code&gt;!&lt;/code&gt;?&lt;/p&gt;</description></item><item><title>5173 is Vite</title><link>https://jakeworth.com/tils/5173-is-vite/</link><pubDate>Thu, 25 Jun 2026 12:51:02 -0400</pubDate><guid>https://jakeworth.com/tils/5173-is-vite/</guid><description>&lt;p&gt;Vite&amp;rsquo;s default port, 5173, is leet code for the project&amp;rsquo;s name:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;5 = &amp;ldquo;V&amp;rdquo; (Roman numerals 😉)&lt;/li&gt;
&lt;li&gt;1 = &amp;ldquo;I&amp;rdquo;&lt;/li&gt;
&lt;li&gt;7 = &amp;ldquo;T&amp;rdquo;&lt;/li&gt;
&lt;li&gt;3 = &amp;ldquo;E&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>Cursor on Current Directory</title><link>https://jakeworth.com/tils/cursor-on-current-directory/</link><pubDate>Wed, 24 Jun 2026 13:39:58 -0400</pubDate><guid>https://jakeworth.com/tils/cursor-on-current-directory/</guid><description>&lt;p&gt;To load Cursor with context of the current directory, use:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;cursor .
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>The Outbox Pattern</title><link>https://jakeworth.com/tils/the-outbox-pattern/</link><pubDate>Thu, 18 Jun 2026 18:02:34 -0400</pubDate><guid>https://jakeworth.com/tils/the-outbox-pattern/</guid><description>&lt;p&gt;Today I learned about the Outbox Pattern.&lt;/p&gt;</description></item><item><title>Node REPL, No Preview</title><link>https://jakeworth.com/tils/node-repl-no-preview/</link><pubDate>Tue, 02 Jun 2026 15:46:17 -0400</pubDate><guid>https://jakeworth.com/tils/node-repl-no-preview/</guid><description>&lt;p&gt;After version v12.17.0, Node&amp;rsquo;s REPL provides a useful preview effect. In this
example, &lt;code&gt;2&lt;/code&gt; is shown in gray &lt;em&gt;before&lt;/em&gt; I hit enter.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-zsh" data-lang="zsh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; + &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But what if I don&amp;rsquo;t want that? Here&amp;rsquo;s a file called &lt;code&gt;repl&lt;/code&gt; that disables it as an option:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;#!/usr/bin/env node
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;repl&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;require&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;node:repl&amp;#39;&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;repl&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;start&lt;/span&gt;({&lt;span style="color:#a6e22e"&gt;preview&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;});
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-zsh" data-lang="zsh"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ./repl
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; + &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No preview.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://nodejs.org/api/repl.html#customizing-repl-output"&gt;Docs&lt;/a&gt;&lt;/p&gt;</description></item><item><title>NVM Install and Use Latest LTS</title><link>https://jakeworth.com/tils/nvm-install-and-use-latest/</link><pubDate>Fri, 29 May 2026 13:49:11 -0400</pubDate><guid>https://jakeworth.com/tils/nvm-install-and-use-latest/</guid><description>&lt;p&gt;With my Node versions managed via NVM, I want to be on the latest LTS. You can
ensure that happens with these commands:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ nvm install --lts
$ nvm alias default lts/*
default -&amp;gt; node (-&amp;gt; v24.16.0)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Law of Demeter Origin Story</title><link>https://jakeworth.com/tils/law-of-demeter-origin-story/</link><pubDate>Mon, 11 May 2026 09:52:13 -0400</pubDate><guid>https://jakeworth.com/tils/law-of-demeter-origin-story/</guid><description>&lt;p&gt;The Law of Demeter is important in object-oriented programming. But where does
&amp;ldquo;Demeter&amp;rdquo; come from?&lt;/p&gt;</description></item><item><title>Filled Emoji With CSS</title><link>https://jakeworth.com/tils/filled-emoji-with-css/</link><pubDate>Fri, 08 May 2026 09:52:29 -0400</pubDate><guid>https://jakeworth.com/tils/filled-emoji-with-css/</guid><description>&lt;p&gt;Today I learned how to fill in an emoji with CSS. Here&amp;rsquo;s an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;filledEmoji&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;color&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;transparent&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;text-shadow&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;0 0 0 #86efac&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>JavaScript Wraparound Index</title><link>https://jakeworth.com/tils/javascript-wraparound-index/</link><pubDate>Thu, 07 May 2026 09:44:10 -0400</pubDate><guid>https://jakeworth.com/tils/javascript-wraparound-index/</guid><description>&lt;p&gt;What I call &amp;ldquo;wraparound&amp;rdquo; are repeatable indices on an array. The common use case is a carousel. Here&amp;rsquo;s how it&amp;rsquo;s done:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;items&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;first&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;middle&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;last&amp;#34;&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;; &lt;span style="color:#75715e"&gt;// Our iterable index
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// &amp;#34;Next&amp;#34; -&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;nextIndex&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;items&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// &amp;lt;- &amp;#34;Previous&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;prevIndex&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;i&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;items&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;) &lt;span style="color:#f92672"&gt;%&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;items&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;length&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>JavaScript String Concatenation</title><link>https://jakeworth.com/tils/javascript-string-concatenation/</link><pubDate>Wed, 06 May 2026 10:39:46 -0400</pubDate><guid>https://jakeworth.com/tils/javascript-string-concatenation/</guid><description>&lt;p&gt;Here&amp;rsquo;s a periodic reminder that JavaScript supports string concatenation with a plus sign:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;foo&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;bar&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;foobar&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>JavaScript Spread a String Into An Array</title><link>https://jakeworth.com/tils/javascript-spread-string-into-array/</link><pubDate>Tue, 05 May 2026 10:49:25 -0400</pubDate><guid>https://jakeworth.com/tils/javascript-spread-string-into-array/</guid><description>&lt;p&gt;Need an array of letters? Here&amp;rsquo;s a trick:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;alpha&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [...&lt;span style="color:#e6db74"&gt;&amp;#39;abcdefghijklmnopqrstuvwxyz&amp;#39;&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>JavaScript Array Join Comma Default Separator</title><link>https://jakeworth.com/tils/javascript-array-join-comma-default-separator/</link><pubDate>Tue, 05 May 2026 09:48:19 -0400</pubDate><guid>https://jakeworth.com/tils/javascript-array-join-comma-default-separator/</guid><description>&lt;p&gt;When you join an array in JavaScript, the default separator is a comma:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;node&lt;/span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#39;j&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;a&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;k&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;e&amp;#39;&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;join&lt;/span&gt;()
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;j,a,k,e&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>JavaScript Bitwise AND</title><link>https://jakeworth.com/tils/javascript-bitwise-and/</link><pubDate>Fri, 01 May 2026 14:53:41 -0400</pubDate><guid>https://jakeworth.com/tils/javascript-bitwise-and/</guid><description>&lt;p&gt;The JavaScript bitwise AND operator (&lt;code&gt;&amp;amp;&lt;/code&gt;) can be used for some real-world tasks, like testing if a number is odd or even.&lt;/p&gt;</description></item><item><title>Vim :Tutor Command</title><link>https://jakeworth.com/tils/vim-tutor-command/</link><pubDate>Wed, 29 Apr 2026 12:25:53 -0400</pubDate><guid>https://jakeworth.com/tils/vim-tutor-command/</guid><description>&lt;p&gt;Longtime Vim users know the &lt;code&gt;vimtutor&lt;/code&gt; program, which teaches you Vim &lt;em&gt;in&lt;/em&gt; Vim. Vim 9.2 shipped with a new &lt;code&gt;:Tutor&lt;/code&gt; command that improves on this.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#a6e22e"&gt;Tutor&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Validate a Container With Docker Ls</title><link>https://jakeworth.com/tils/validate-a-container-with-docker-pull/</link><pubDate>Thu, 09 Apr 2026 13:43:05 -0400</pubDate><guid>https://jakeworth.com/tils/validate-a-container-with-docker-pull/</guid><description>&lt;p&gt;Is a Docker container available on a registry? Here&amp;rsquo;s how I&amp;rsquo;d check, right from the CLI:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;docker image ls &amp;lt;container-name&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Ease Into CI Rigor With Globs</title><link>https://jakeworth.com/tils/ease-into-ci-rigor-with-globs/</link><pubDate>Sun, 15 Mar 2026 11:06:33 -0400</pubDate><guid>https://jakeworth.com/tils/ease-into-ci-rigor-with-globs/</guid><description>&lt;p&gt;When adding CI checks, you can gradually increase rigor while easing your
codebase into a better place.&lt;/p&gt;</description></item><item><title>Overwrite vs. Append</title><link>https://jakeworth.com/tils/overwrite-vs-append/</link><pubDate>Fri, 13 Mar 2026 16:01:22 -0400</pubDate><guid>https://jakeworth.com/tils/overwrite-vs-append/</guid><description>&lt;p&gt;I use the append &lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; and overwrite &lt;code&gt;&amp;gt;&lt;/code&gt; redirection operators all the time. Today I&amp;rsquo;d like to share a simple mental model I&amp;rsquo;ve developed for remembering which is which.&lt;/p&gt;</description></item><item><title>Git Apply Diff</title><link>https://jakeworth.com/tils/git-apply-diff/</link><pubDate>Fri, 27 Feb 2026 16:51:25 -0500</pubDate><guid>https://jakeworth.com/tils/git-apply-diff/</guid><description>&lt;p&gt;One of my favorite Git tricks is shoveling changes to a Git diff and then applying them later.&lt;/p&gt;</description></item><item><title>Docker Service Healthy</title><link>https://jakeworth.com/tils/docker-service-healthy/</link><pubDate>Fri, 20 Feb 2026 10:08:34 -0500</pubDate><guid>https://jakeworth.com/tils/docker-service-healthy/</guid><description>&lt;p&gt;Docker gives you a way to control startup, while codifying that one container depends on others.&lt;/p&gt;</description></item><item><title>Docker Compose Override</title><link>https://jakeworth.com/tils/docker-compose-override/</link><pubDate>Fri, 20 Feb 2026 10:04:38 -0500</pubDate><guid>https://jakeworth.com/tils/docker-compose-override/</guid><description>&lt;p&gt;Need to override some Docker configuration locally? Too easy!&lt;/p&gt;</description></item><item><title>Installing Vim on a Remote Server</title><link>https://jakeworth.com/tils/installing-vim-on-a-remote-server/</link><pubDate>Fri, 13 Feb 2026 16:46:12 -0500</pubDate><guid>https://jakeworth.com/tils/installing-vim-on-a-remote-server/</guid><description>&lt;p&gt;Vim-tiny is a great choice for remote server work.&lt;/p&gt;</description></item><item><title>Initialize With npm init</title><link>https://jakeworth.com/tils/initialize-with-npm-init/</link><pubDate>Thu, 12 Feb 2026 11:19:46 -0500</pubDate><guid>https://jakeworth.com/tils/initialize-with-npm-init/</guid><description>&lt;p&gt;Most JavaScript projects come with a &lt;code&gt;package.json&lt;/code&gt;. But what if you want to make a new one?&lt;/p&gt;</description></item><item><title>Gibibyte is Not a Gigabyte</title><link>https://jakeworth.com/tils/gibibyte-is-not-a-gigabyte/</link><pubDate>Mon, 09 Feb 2026 13:47:12 -0500</pubDate><guid>https://jakeworth.com/tils/gibibyte-is-not-a-gigabyte/</guid><description>&lt;p&gt;&amp;ldquo;The server is 200 GiBs.&amp;rdquo; &amp;ldquo;Don&amp;rsquo;t you mean GBs?&amp;rdquo; &amp;ldquo;No, I don&amp;rsquo;t!&amp;rdquo;&lt;/p&gt;</description></item><item><title>MySQL Binlogs</title><link>https://jakeworth.com/tils/mysql-binlogs/</link><pubDate>Mon, 09 Feb 2026 13:32:51 -0500</pubDate><guid>https://jakeworth.com/tils/mysql-binlogs/</guid><description>&lt;p&gt;I recently dug into the wonderful world of MySQL binlogs! Here a few learnings.&lt;/p&gt;</description></item><item><title>Recognizing ASCII</title><link>https://jakeworth.com/tils/recognizing-ascii/</link><pubDate>Mon, 09 Feb 2026 13:18:37 -0500</pubDate><guid>https://jakeworth.com/tils/recognizing-ascii/</guid><description>&lt;p&gt;When you see a list of numbers in a log or stack overflow, it&amp;rsquo;s often ASCII
(American Standard Code for Information Interchange)! Here&amp;rsquo;s how to recognize
and read it.&lt;/p&gt;</description></item><item><title>Who Owns This Program?</title><link>https://jakeworth.com/tils/who-owns-this-program/</link><pubDate>Mon, 09 Feb 2026 10:36:33 -0500</pubDate><guid>https://jakeworth.com/tils/who-owns-this-program/</guid><description>&lt;p&gt;I&amp;rsquo;ve got a command &lt;code&gt;docker&lt;/code&gt; on my machine. I need to upgrade it. So, who owns it?&lt;/p&gt;</description></item><item><title>Writing the DOM with fs</title><link>https://jakeworth.com/tils/writing-the-dom-with-fs/</link><pubDate>Fri, 30 Jan 2026 11:12:52 -0500</pubDate><guid>https://jakeworth.com/tils/writing-the-dom-with-fs/</guid><description>&lt;p&gt;How can I output the entire DOM to a file in a JavaScript test?&lt;/p&gt;</description></item><item><title>Git Porcelain and Plumbing 🚽</title><link>https://jakeworth.com/tils/git-porcelain-and-plumbing/</link><pubDate>Mon, 26 Jan 2026 16:53:11 -0500</pubDate><guid>https://jakeworth.com/tils/git-porcelain-and-plumbing/</guid><description>&lt;p&gt;Git has two kinds of commands: &amp;ldquo;porcelain&amp;rdquo; and &amp;ldquo;plumbing&amp;rdquo;.&lt;/p&gt;</description></item><item><title>Calculating With Bc</title><link>https://jakeworth.com/tils/calculating-with-bc/</link><pubDate>Wed, 07 Jan 2026 09:48:26 -0500</pubDate><guid>https://jakeworth.com/tils/calculating-with-bc/</guid><description>&lt;p&gt;Today I accidentally I found a calculator on my computer, &lt;code&gt;bc&lt;/code&gt;. Let&amp;rsquo;s look at it!&lt;/p&gt;</description></item><item><title>Rebuilds on Write With Nodemon</title><link>https://jakeworth.com/tils/rebuilds-on-write-with-nodemon/</link><pubDate>Tue, 30 Dec 2025 16:42:28 -0500</pubDate><guid>https://jakeworth.com/tils/rebuilds-on-write-with-nodemon/</guid><description>&lt;p&gt;I&amp;rsquo;ve been hacking on a TypeScript file all day, but I need transpiled JavaScript for any testing. How did I reduce cycle time (and mitigate many chances to forget to build at all)?&lt;/p&gt;</description></item><item><title>MCP Stdio and Stdout</title><link>https://jakeworth.com/tils/mcp-stdio-and-stdout/</link><pubDate>Tue, 30 Dec 2025 11:33:06 -0500</pubDate><guid>https://jakeworth.com/tils/mcp-stdio-and-stdout/</guid><description>&lt;p&gt;In MCP server code using stdio, you can&amp;rsquo;t use any functions that print to stdout.&lt;/p&gt;</description></item><item><title>tsc watch</title><link>https://jakeworth.com/tils/tsc-watch/</link><pubDate>Mon, 29 Dec 2025 13:51:45 -0500</pubDate><guid>https://jakeworth.com/tils/tsc-watch/</guid><description>&lt;p&gt;Watch and re-transpile any TypeScript file with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;tsc file.ts --watch
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Observable Exceptions That Don't Crash</title><link>https://jakeworth.com/tils/observable-exceptions-that-dont-crash/</link><pubDate>Wed, 17 Dec 2025 09:53:09 -0500</pubDate><guid>https://jakeworth.com/tils/observable-exceptions-that-dont-crash/</guid><description>&lt;p&gt;Throwing a JavaScript &lt;code&gt;Error&lt;/code&gt; test to your observability tool? There&amp;rsquo;s a better way.&lt;/p&gt;</description></item><item><title>npmrc "engine-strict"</title><link>https://jakeworth.com/tils/npm-install-engine-strict/</link><pubDate>Tue, 16 Dec 2025 16:38:36 -0500</pubDate><guid>https://jakeworth.com/tils/npm-install-engine-strict/</guid><description>&lt;p&gt;Suppose your &lt;code&gt;package.json&lt;/code&gt; specifies a Node engine of greater than or equal 24. Does this mean all engineers on your team will use Node 24? No, unless you use this one weird trick!&lt;/p&gt;</description></item><item><title>Hello World from MCP!</title><link>https://jakeworth.com/tils/hello-world-from-mcp/</link><pubDate>Fri, 12 Dec 2025 00:00:00 +0000</pubDate><guid>https://jakeworth.com/tils/hello-world-from-mcp/</guid><description>&lt;p&gt;Hello World! Today I&amp;rsquo;m posting a TIL using MCP (Model Context Protocol).&lt;/p&gt;</description></item><item><title>Input Redirection Operator</title><link>https://jakeworth.com/tils/input-redirection-operator/</link><pubDate>Mon, 08 Dec 2025 18:07:19 -0500</pubDate><guid>https://jakeworth.com/tils/input-redirection-operator/</guid><description>&lt;p&gt;I&amp;rsquo;ve been known to &lt;code&gt;cat README.md | pbcopy&lt;/code&gt; a file. There&amp;rsquo;s a better way: the input redirection operator!&lt;/p&gt;</description></item><item><title>Tmux Toggle Sessions</title><link>https://jakeworth.com/tils/tmux-toggle-sessions/</link><pubDate>Thu, 04 Dec 2025 10:49:44 -0500</pubDate><guid>https://jakeworth.com/tils/tmux-toggle-sessions/</guid><description>&lt;p&gt;To toggle back and forth between two Tmux sessions, use &lt;code&gt;&amp;lt;leader&amp;gt;-L&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Disable DRF Browsable API</title><link>https://jakeworth.com/tils/disable-drf-browsable-api/</link><pubDate>Wed, 03 Dec 2025 12:04:51 -0500</pubDate><guid>https://jakeworth.com/tils/disable-drf-browsable-api/</guid><description>&lt;p&gt;Django Rest Framework includes a UI for interacting with your API. Here&amp;rsquo;s how to
turn it off.&lt;/p&gt;</description></item><item><title>Import React and React 17 JSX Transform</title><link>https://jakeworth.com/tils/import-react-and-react-17-jsx-transform/</link><pubDate>Mon, 01 Dec 2025 18:21:26 -0500</pubDate><guid>https://jakeworth.com/tils/import-react-and-react-17-jsx-transform/</guid><description>&lt;p&gt;I&amp;rsquo;ve written before about the two competing ways to import React, but after React 17, you don&amp;rsquo;t need either.&lt;/p&gt;</description></item><item><title>Docker Build No Cache</title><link>https://jakeworth.com/tils/docker-build-no-cache/</link><pubDate>Fri, 21 Nov 2025 10:50:28 -0500</pubDate><guid>https://jakeworth.com/tils/docker-build-no-cache/</guid><description>&lt;p&gt;Sometimes your Docker build is cached, and you need to build without cache.&lt;/p&gt;</description></item><item><title>Timestamped Branch</title><link>https://jakeworth.com/tils/timestamped-branch/</link><pubDate>Thu, 20 Nov 2025 16:53:29 -0500</pubDate><guid>https://jakeworth.com/tils/timestamped-branch/</guid><description>&lt;p&gt;Git prevents branches with the same name. But sometimes, I want to re-use a name! Here&amp;rsquo;s my workaround.&lt;/p&gt;</description></item><item><title>Why Keep Binaries Out of Version Control</title><link>https://jakeworth.com/tils/why-keep-binaries-out-of-version-control/</link><pubDate>Thu, 20 Nov 2025 10:48:23 -0500</pubDate><guid>https://jakeworth.com/tils/why-keep-binaries-out-of-version-control/</guid><description>&lt;p&gt;&amp;ldquo;Keep binaries out of version control&amp;rdquo; is a truth I&amp;rsquo;ve always held, but I recently learned more about why.&lt;/p&gt;</description></item><item><title>Set -euo pipefail</title><link>https://jakeworth.com/tils/set-euo-pipefail/</link><pubDate>Mon, 17 Nov 2025 17:26:27 -0500</pubDate><guid>https://jakeworth.com/tils/set-euo-pipefail/</guid><description>&lt;p&gt;My site&amp;rsquo;s build script has a &lt;code&gt;set&lt;/code&gt; command; but what does it do?&lt;/p&gt;</description></item><item><title>Django Routing 101</title><link>https://jakeworth.com/tils/django-routing-101/</link><pubDate>Fri, 07 Nov 2025 16:47:58 -0500</pubDate><guid>https://jakeworth.com/tils/django-routing-101/</guid><description>&lt;p&gt;Something I&amp;rsquo;ve taken a while to get under my fingers is Django&amp;rsquo;s URL routing conventions. Here&amp;rsquo;s a brief summary.&lt;/p&gt;</description></item><item><title>Tail Docker Logs</title><link>https://jakeworth.com/tils/tail-docker-logs/</link><pubDate>Wed, 05 Nov 2025 16:15:50 -0500</pubDate><guid>https://jakeworth.com/tils/tail-docker-logs/</guid><description>&lt;p&gt;Here&amp;rsquo;s how you tail a Docker log.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;docker logs --follow &amp;lt;container_name&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;See &lt;code&gt;docker logs --help&lt;/code&gt; for more.&lt;/p&gt;</description></item><item><title>MySQL Vertical Result</title><link>https://jakeworth.com/tils/mysql-vertical-result/</link><pubDate>Mon, 27 Oct 2025 11:19:36 -0400</pubDate><guid>https://jakeworth.com/tils/mysql-vertical-result/</guid><description>&lt;p&gt;MySQL&amp;rsquo;s display is tabular:&lt;/p&gt;</description></item><item><title>Docker Compose Watch</title><link>https://jakeworth.com/tils/docker-compose-watch/</link><pubDate>Fri, 12 Sep 2025 09:10:35 -0400</pubDate><guid>https://jakeworth.com/tils/docker-compose-watch/</guid><description>&lt;p&gt;One of my projects features a Dockerized API. The dev process was: write a file, rebuild container, and restart container. There&amp;rsquo;s a better way!&lt;/p&gt;</description></item><item><title>Git Apply a Commit in Reverse</title><link>https://jakeworth.com/tils/git-apply-a-commit-in-reverse/</link><pubDate>Wed, 30 Jul 2025 14:48:55 -0400</pubDate><guid>https://jakeworth.com/tils/git-apply-a-commit-in-reverse/</guid><description>&lt;p&gt;Sometimes I&amp;rsquo;ll be looking at a Git commit online, and want to put my dev environment in a world where the commit is un-applied. This can be achieved by applying it in reverse.&lt;/p&gt;</description></item><item><title>Origin of the Term Cherry MX</title><link>https://jakeworth.com/tils/origin-of-the-term-cherry-mx/</link><pubDate>Tue, 22 Jul 2025 16:34:44 -0400</pubDate><guid>https://jakeworth.com/tils/origin-of-the-term-cherry-mx/</guid><description>&lt;p&gt;I&amp;rsquo;ve been buying keyboards with Cherry MX switches for a decade, browns and a few blues. Today, I learned that MX stands for &amp;ldquo;Mechanical X-Point&amp;rdquo;– &amp;ldquo;X&amp;rdquo; for the x-shape of the keyboard stem you can see when you remove the keycap.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://en.wikipedia.org/wiki/Cherry_AG"&gt;https://en.wikipedia.org/wiki/Cherry_AG&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Origin of ActiveRecord</title><link>https://jakeworth.com/tils/origin-of-activerecord/</link><pubDate>Tue, 22 Jul 2025 16:33:47 -0400</pubDate><guid>https://jakeworth.com/tils/origin-of-activerecord/</guid><description>&lt;p&gt;As a long-time Ruby on Rails programmer, I thought that the name ActiveRecord –the model layer of Rails&amp;rsquo; MVC– was branding. I didn&amp;rsquo;t know that it&amp;rsquo;s an architectural pattern, described by Martin Fowler in the 2003 book Patterns of Enterprise Application Architecture.&lt;/p&gt;
&lt;p&gt;An object that wraps a row in a database table or view, encapsulates the database access, and adds domain logic on that data.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://www.martinfowler.com/eaaCatalog/activeRecord.html"&gt;https://www.martinfowler.com/eaaCatalog/activeRecord.html&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Editing in Nodes REPL Editor</title><link>https://jakeworth.com/tils/editing-in-nodes-repl-editor/</link><pubDate>Tue, 22 Jul 2025 16:32:43 -0400</pubDate><guid>https://jakeworth.com/tils/editing-in-nodes-repl-editor/</guid><description>&lt;p&gt;The Node REPL has its own editor:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;node
&amp;gt; .editor
// Entering editor mode (Ctrl+D to finish, Ctrl+C to cancel)
const increment = (array) =&amp;gt; array.map(item =&amp;gt; item + 1)
increment([1,2,3])
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Exit and evaluate with Ctrl+D:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[ 2, 3, 4 ]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I&amp;rsquo;d use this to experiment with JavaScript API&amp;rsquo;s without leaving my terminal-based IDE.&lt;/p&gt;</description></item><item><title>Vim Mappings Verbose</title><link>https://jakeworth.com/tils/vim-mappings-verbose/</link><pubDate>Tue, 22 Jul 2025 16:31:22 -0400</pubDate><guid>https://jakeworth.com/tils/vim-mappings-verbose/</guid><description>&lt;p&gt;I have a Vim normal mode mapping, and I don&amp;rsquo;t know where it comes from. My Vim config, a plugin, somewhere else? nmap shows me the mapping:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:nmap gsp
n gsp * 1z=
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And verbose nmap shows me where it comes from:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:verbose nmap gsp
n gsp * 1z=
Last set from ~/.vimrc line 111
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The setting is coming from inside the &lt;code&gt;.vimrc&lt;/code&gt;!&lt;/p&gt;</description></item><item><title>Example.com in Your Data</title><link>https://jakeworth.com/tils/example-dot-com-in-your-data/</link><pubDate>Tue, 22 Jul 2025 16:29:59 -0400</pubDate><guid>https://jakeworth.com/tils/example-dot-com-in-your-data/</guid><description>&lt;p&gt;It&amp;rsquo;s common practice to create usernames in a non-production database like &amp;ldquo;&lt;a href="mailto:dev@example.com"&gt;dev@example.com&lt;/a&gt;&amp;rdquo; or &amp;ldquo;&lt;a href="mailto:customer@example.org"&gt;customer@example.org&lt;/a&gt;&amp;rdquo;. We do this to say: &amp;ldquo;This is just an example!&amp;rdquo; But there&amp;rsquo;s a more to the story.&lt;/p&gt;</description></item><item><title>Har Files in Chrome</title><link>https://jakeworth.com/tils/har-files-in-chrome/</link><pubDate>Tue, 22 Jul 2025 16:28:30 -0400</pubDate><guid>https://jakeworth.com/tils/har-files-in-chrome/</guid><description>&lt;p&gt;Today I learned about the &lt;code&gt;.har&lt;/code&gt; extension (via Wikipedia):&lt;/p&gt;</description></item><item><title>Unpacking MessagePack</title><link>https://jakeworth.com/tils/unpacking-msgpack/</link><pubDate>Thu, 05 Jun 2025 16:45:33 -0400</pubDate><guid>https://jakeworth.com/tils/unpacking-msgpack/</guid><description>&lt;p&gt;SALT messages are encoded with a library called &lt;code&gt;msgpack&lt;/code&gt;, the Python implementation
of &lt;a href="https://msgpack.org/"&gt;MessagePack&lt;/a&gt;. How can we read them?&lt;/p&gt;</description></item><item><title>Directories Ending in .d</title><link>https://jakeworth.com/tils/directories-ending-in-dot-d/</link><pubDate>Wed, 04 Jun 2025 17:34:59 -0400</pubDate><guid>https://jakeworth.com/tils/directories-ending-in-dot-d/</guid><description>&lt;p&gt;Today I learned about why directories in a project might have names ending in &amp;lsquo;dot d&amp;rsquo;, such as &lt;code&gt;minion.d/&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Python String Interpolation</title><link>https://jakeworth.com/tils/python-string-interpolation/</link><pubDate>Tue, 27 May 2025 22:00:15 -0400</pubDate><guid>https://jakeworth.com/tils/python-string-interpolation/</guid><description>&lt;p&gt;Python string interpolation is available via few of interfaces, as &lt;a href="https://til.hashrocket.com/posts/iiri0m4gpb-string-interpolation-in-python"&gt;Chris at Hashrocket&lt;/a&gt; taught me.&lt;/p&gt;</description></item><item><title>Light Bulb Series Encoding</title><link>https://jakeworth.com/tils/light-bulb-series-encoding/</link><pubDate>Fri, 23 May 2025 12:03:36 -0400</pubDate><guid>https://jakeworth.com/tils/light-bulb-series-encoding/</guid><description>&lt;p&gt;I needed to replace an &amp;ldquo;A19&amp;rdquo; light bulb. What does &amp;ldquo;A19&amp;rdquo; mean?&lt;/p&gt;</description></item><item><title>Vim Jump to Previous Occurrence</title><link>https://jakeworth.com/tils/vim-jump-to-previous-occurrence/</link><pubDate>Tue, 20 May 2025 19:08:16 -0400</pubDate><guid>https://jakeworth.com/tils/vim-jump-to-previous-occurrence/</guid><description>&lt;p&gt;In Vim Normal mode, &lt;code&gt;*&lt;/code&gt; searches forward for the next occurrence of word. But what goes back?&lt;/p&gt;</description></item><item><title>Print Python Function Definition With Getsource</title><link>https://jakeworth.com/tils/print-python-function-definition-with-getsource/</link><pubDate>Fri, 16 May 2025 11:01:29 -0400</pubDate><guid>https://jakeworth.com/tils/print-python-function-definition-with-getsource/</guid><description>&lt;p&gt;If I&amp;rsquo;ve defined a function in the Python REPL, I can read its definition with
&lt;code&gt;inspect.getsource&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Python REPL Help</title><link>https://jakeworth.com/tils/python-repl-help/</link><pubDate>Fri, 16 May 2025 10:49:29 -0400</pubDate><guid>https://jakeworth.com/tils/python-repl-help/</guid><description>&lt;p&gt;In the Python REPL, the &lt;code&gt;help&lt;/code&gt; function provides a help message about its argument.&lt;/p&gt;</description></item><item><title>How to Start a Standup in Jira</title><link>https://jakeworth.com/tils/jira-standup-mode/</link><pubDate>Thu, 01 May 2025 20:51:07 -0400</pubDate><guid>https://jakeworth.com/tils/jira-standup-mode/</guid><description>&lt;p&gt;Jira does have a &amp;ldquo;Start Standup&amp;rdquo; button, but it&amp;rsquo;s hidden and not well documented.&lt;/p&gt;</description></item><item><title>Kill MacOS Processes by Name</title><link>https://jakeworth.com/tils/kill-macos-processes-by-name/</link><pubDate>Mon, 17 Mar 2025 16:51:09 -0400</pubDate><guid>https://jakeworth.com/tils/kill-macos-processes-by-name/</guid><description>&lt;p&gt;I have a cron job that opens a program every day at a certain time. How can I also close it with a cron job?&lt;/p&gt;</description></item><item><title>pbcopy, no cat</title><link>https://jakeworth.com/tils/pbcopy-no-cat/</link><pubDate>Wed, 05 Mar 2025 10:07:24 -0500</pubDate><guid>https://jakeworth.com/tils/pbcopy-no-cat/</guid><description>&lt;p&gt;My friend Josh recently wrote about a common mistake using &lt;code&gt;pbcopy&lt;/code&gt;, Apple&amp;rsquo;s pasteboard utility.&lt;/p&gt;</description></item><item><title>Pause Script Execution in Chrome</title><link>https://jakeworth.com/tils/pause-script-execution-in-chrome/</link><pubDate>Tue, 04 Mar 2025 09:28:10 -0500</pubDate><guid>https://jakeworth.com/tils/pause-script-execution-in-chrome/</guid><description>&lt;p&gt;Anytime Chrome loads a webpage, you can pause script execution without a debugger.&lt;/p&gt;</description></item><item><title>Either/Or Props in TypeScript</title><link>https://jakeworth.com/tils/either-or-props-in-typescript/</link><pubDate>Mon, 22 Jul 2024 16:32:43 -0400</pubDate><guid>https://jakeworth.com/tils/either-or-props-in-typescript/</guid><description>&lt;p&gt;Sometimes in TypeScript we&amp;rsquo;d like to say a function can either have one typed prop, or the other, never both and never neither. This can be achieved with a union type and type &lt;code&gt;never&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ts" data-lang="ts"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Props&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;markdown&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;copy?&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;never&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#a6e22e"&gt;markdown?&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;never&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;copy&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;string&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;component&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; ({ &lt;span style="color:#a6e22e"&gt;markdown&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;copy&lt;/span&gt; }&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Props&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;markdown&lt;/span&gt; &lt;span style="color:#f92672"&gt;?&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;parseMarkdown&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;markdown&lt;/span&gt;) &lt;span style="color:#f92672"&gt;:&lt;/span&gt; &amp;lt;&amp;gt;&lt;span style="color:#a6e22e"&gt;copy&lt;/span&gt;&amp;lt;/&amp;gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;component&lt;/span&gt;({ &lt;span style="color:#a6e22e"&gt;markdown&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;### Important&amp;#34;&lt;/span&gt; })) &lt;span style="color:#75715e"&gt;// &amp;lt;h3&amp;gt;Important&amp;lt;/h3&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;component&lt;/span&gt;({ &lt;span style="color:#a6e22e"&gt;copy&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Just information&amp;#34;&lt;/span&gt; })) &lt;span style="color:#75715e"&gt;// &amp;lt;&amp;gt;Just information&amp;lt;/&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;component&lt;/span&gt;({ &lt;span style="color:#a6e22e"&gt;copy&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Just information&amp;#34;&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;markdown&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;#34;###&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;That&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;conflicts&lt;/span&gt; })) &lt;span style="color:#75715e"&gt;// ❌ Type error
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;component&lt;/span&gt;({})) &lt;span style="color:#75715e"&gt;// ❌ Type error
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Our component can receive a string of markdown, which it will parse, or raw copy, which it will not parse. Always just one, never both, and never neither.&lt;/p&gt;</description></item><item><title>Encoding Plus Signs in URLS</title><link>https://jakeworth.com/tils/encoding-plus-signs-in-urls/</link><pubDate>Mon, 22 Jul 2024 16:32:43 -0400</pubDate><guid>https://jakeworth.com/tils/encoding-plus-signs-in-urls/</guid><description>&lt;p&gt;If you&amp;rsquo;re creating a hyperlink with query params, and those param values
can have plus signs, it&amp;rsquo;s important to encode them values. We do this with
&lt;code&gt;encodeURIComponent&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;email&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`jake+testing@example.com`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;loginLink&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;`https://example.com/login?email=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;encodeURIComponent(&lt;span style="color:#a6e22e"&gt;email&lt;/span&gt;)&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;window.&lt;span style="color:#a6e22e"&gt;open&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;loginLink&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;If you skip this step and try to read the query parameters received by
&amp;rsquo;example.com&amp;rsquo; your email param value may be interpreted as with spaces instead
of pluses, i.e. &lt;code&gt;jake testing@example.com&lt;/code&gt;. Per the &lt;a href="https://www.w3.org/Addressing/URL/4_URI_Recommentations.html#:~:text=Within%20the%20query%20string%2C%20the,plus%20signs%20must%20be%20encoded."&gt;docs&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Within the query string, the plus sign is reserved as shorthand notation for
a space. Therefore, real plus signs must be encoded. This method was used to
make query URIs easier to pass in systems which did not allow spaces.&lt;/p&gt;</description></item><item><title>Load a Dependency in the Node REPL</title><link>https://jakeworth.com/tils/load-a-dependency-in-node-repl/</link><pubDate>Thu, 11 Jul 2024 10:42:11 -0400</pubDate><guid>https://jakeworth.com/tils/load-a-dependency-in-node-repl/</guid><description>&lt;p&gt;Exploring your JS dependencies locally is a great way to learn and experiment. Here&amp;rsquo;s
how to load a dependency from your &lt;code&gt;/node_modules&lt;/code&gt; directory into the Node REPL.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ node
&amp;gt; cn = require(&amp;#39;classnames&amp;#39;)
&amp;gt; cn(&amp;#34;always&amp;#34;, { never: false, sometimes: true })
&amp;#39;always sometimes&amp;#39;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Filtering By Identity</title><link>https://jakeworth.com/tils/filtering-by-identity/</link><pubDate>Thu, 27 Jun 2024 09:57:29 -0400</pubDate><guid>https://jakeworth.com/tils/filtering-by-identity/</guid><description>&lt;p&gt;I&amp;rsquo;m reading &lt;em&gt;Functional-Light JavaScript&lt;/em&gt; by Kyle Simpson, and learning a lot!
Today I learned about the functional programming utility known as &amp;lsquo;identity&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;Identity is a unary function that simply returns its argument. A simple idea
that can be powerfully applied, as JavaScript coerces the returned argument to
boolean:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;identity&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;arg&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;arg&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; [&lt;span style="color:#e6db74"&gt;&amp;#34;&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;keep&amp;#34;&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;undefined&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;these&amp;#34;&lt;/span&gt;].&lt;span style="color:#a6e22e"&gt;filter&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;identity&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;[ &lt;span style="color:#e6db74"&gt;&amp;#39;keep&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;these&amp;#39;&lt;/span&gt; ]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve done something similar for years by filtering to boolean, or writing my own
(I didn&amp;rsquo;t know it had this name) anonymous identity function.&lt;/p&gt;</description></item><item><title>Show How A File Is Ignored In Git</title><link>https://jakeworth.com/tils/show-how-a-file-is-ignored-in-git/</link><pubDate>Fri, 31 May 2024 10:21:44 -0400</pubDate><guid>https://jakeworth.com/tils/show-how-a-file-is-ignored-in-git/</guid><description>&lt;p&gt;Today I solved a mystery: a file was being Git-ignored in a new project that didn&amp;rsquo;t have a
&lt;code&gt;.gitignore&lt;/code&gt;. Here&amp;rsquo;s me learning this by trying and failing to add it:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ git add destroy.sh
The following paths are ignored by one of your .gitignore files:
destroy.sh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This output tells me some &lt;code&gt;.gitignore&lt;/code&gt; is telling Git to ignore my script. Another way to confirm this is the &lt;code&gt;check-ignore&lt;/code&gt; command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ git check-ignore destroy.sh
destroy.sh
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The output here is the match; a file named &lt;code&gt;destroy.sh&lt;/code&gt; is indeed being ignored. But how? We can answer that question
with the &lt;code&gt;-v&lt;/code&gt; flag:&lt;/p&gt;</description></item><item><title>Block a URL in Chrome DevTools</title><link>https://jakeworth.com/tils/block-a-url-in-chrome-devtools/</link><pubDate>Fri, 24 May 2024 09:33:24 -0400</pubDate><guid>https://jakeworth.com/tils/block-a-url-in-chrome-devtools/</guid><description>&lt;p&gt;I&amp;rsquo;m using a JavaScript text editor library and when it fails to load, there is
no form field on the page at all. While pondering that potential issue, I
learned how to block a URL in Chrome&amp;rsquo;s DevTools.&lt;/p&gt;
&lt;p&gt;There are a few way to do this; the most direct for me is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Open DevTools and the Network Tab&lt;/li&gt;
&lt;li&gt;Click &amp;ldquo;JS&amp;rdquo; and find the JavaScript file I want to block&lt;/li&gt;
&lt;li&gt;Right-click and choose &amp;ldquo;Block request URL&amp;rdquo; or &amp;ldquo;Block request domain&amp;rdquo;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Reload the page to see the result.&lt;/p&gt;</description></item><item><title>Reading a Button's Value on Submit</title><link>https://jakeworth.com/tils/reading-a-buttons-value-on-submit/</link><pubDate>Fri, 24 May 2024 09:25:37 -0400</pubDate><guid>https://jakeworth.com/tils/reading-a-buttons-value-on-submit/</guid><description>&lt;p&gt;Complex HTML forms often end up with multiple submit buttons. Consider a form
for taxes: there&amp;rsquo;s a button to save a draft and another button to submit for
processing. They both trigger the submit action on the same form. How could we
accomplish this while keeping the buttons fairly simple?&lt;/p&gt;
&lt;p&gt;One solution is to set the buttons&amp;rsquo; value:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;form&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onsubmit&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;{onSubmit}&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#75715e"&gt;&amp;lt;!-- Form fields here --&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;input&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;submit&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;save&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;input&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;submit&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;value&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;submit&amp;#34;&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;form&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Then in the submit handler, we read the value.&lt;/p&gt;</description></item><item><title>Read Zsh Builtin Manual Pages</title><link>https://jakeworth.com/tils/read-zsh-builtin-manual-pages/</link><pubDate>Wed, 22 May 2024 12:30:02 -0400</pubDate><guid>https://jakeworth.com/tils/read-zsh-builtin-manual-pages/</guid><description>&lt;p&gt;In Zsh, if you type &lt;code&gt;man cd&lt;/code&gt;, instead of a manual page, you&amp;rsquo;ll get this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;See the built-in command description in the appropriate shell manual page.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;To see Zsh&amp;rsquo;s implementation of &lt;code&gt;cd&lt;/code&gt;, we need to view Zsh&amp;rsquo;s built-in man page:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;man zshbuiltins
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Autofocus a Form Field</title><link>https://jakeworth.com/tils/autofocus-a-form-field/</link><pubDate>Tue, 21 May 2024 10:50:17 -0400</pubDate><guid>https://jakeworth.com/tils/autofocus-a-form-field/</guid><description>&lt;p&gt;&lt;code&gt;autofocus&lt;/code&gt; is a global attribute that sets a field as focused on page load.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;input&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;first_name&amp;#34;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;autofocus&lt;/span&gt; /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;No JavaScript required!&lt;/p&gt;
&lt;p&gt;A use case could be a new customer form that an employee fills out multiple
times a day. By autofocusing the first name field, you could save that
employee thousands of clicks.&lt;/p&gt;
&lt;p&gt;Carefully consider user experience and accessibility before using this attribute.&lt;/p&gt;
&lt;p&gt;Docs: &lt;a href="https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus"&gt;https://developer.mozilla.org/en-US/docs/Web/HTML/Global_attributes/autofocus&lt;/a&gt;&lt;/p&gt;</description></item><item><title>RDS Breaks My Radio Clock</title><link>https://jakeworth.com/tils/rds-breaks-my-clock/</link><pubDate>Sun, 19 May 2024 16:04:43 -0400</pubDate><guid>https://jakeworth.com/tils/rds-breaks-my-clock/</guid><description>&lt;p&gt;When using radio, you might experience a strange phenomenon: the radio clock
refuses to stay correctly set. I saw this recently on a car stereo that
continued to reset its clock to an hour early for my timezone.&lt;/p&gt;
&lt;p&gt;The culprit is a system called RDS, Radio Data System. RDS allows radio
transmitters to encode their program information, station identification,
and&amp;hellip; the local time.&lt;/p&gt;
&lt;p&gt;Though I didn&amp;rsquo;t have a tool to debug the signal on hand, my theory is that a
local radio station was sending the incorrect time of 10:15 AM instead 11:15
AM. My car was read it and preferred this data. We live near the border of the
Atlantic timezone, so that&amp;rsquo;s one reason an incorrect message could have been
sent. Disabling the RDS Clock Sync feature and setting the time correctly fixed
the issue.&lt;/p&gt;</description></item><item><title>Understanding Scrollbar Visibility</title><link>https://jakeworth.com/tils/understanding-scrollbar-visiblity/</link><pubDate>Thu, 11 Apr 2024 09:59:30 -0400</pubDate><guid>https://jakeworth.com/tils/understanding-scrollbar-visiblity/</guid><description>&lt;p&gt;When doing web programming in a context where scroll might be expected, you may
see some surprising behavior in the scrollable HTML– an inexplicable gray bar on
the bottom or right of the element.&lt;/p&gt;</description></item><item><title>Re-render Child Component By Changing Key</title><link>https://jakeworth.com/tils/rerender-child-component-by-changing-key/</link><pubDate>Tue, 05 Mar 2024 13:29:38 -0500</pubDate><guid>https://jakeworth.com/tils/rerender-child-component-by-changing-key/</guid><description>&lt;p&gt;Today I had a situation where I wanted a child component to re-render on
command. The solution I found was to to put a key on it, and then change the
key when the re-render is desired.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Parent&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; [&lt;span style="color:#a6e22e"&gt;childKey&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;setChildKey&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;useState&lt;/span&gt;(&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;rerenderForm&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; () &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;setChildKey&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;childKey&lt;/span&gt; &lt;span style="color:#f92672"&gt;+&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;);
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;return&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;onClick&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;rerenderForm&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;button&amp;#34;&lt;/span&gt;&amp;gt;&lt;span style="color:#a6e22e"&gt;Rerender&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;the&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;form&lt;/span&gt;&lt;span style="color:#f92672"&gt;!&lt;/span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;Form&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;childKey&lt;/span&gt;} /&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; )
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In this example, which the button is clicked, our &lt;code&gt;childKey&lt;/code&gt; is incremented. To
paraphrase the React docs, when the key changes, React &amp;ldquo;loses track&amp;rdquo; of the
form. And because of the new key, at the same time React sees a new form; a
re-render has occurred.&lt;/p&gt;</description></item><item><title>Inferred Controller Parameters</title><link>https://jakeworth.com/tils/controller-parameters-infered-from-the-model/</link><pubDate>Fri, 01 Mar 2024 16:54:46 -0500</pubDate><guid>https://jakeworth.com/tils/controller-parameters-infered-from-the-model/</guid><description>&lt;p&gt;Be careful when making a network request like this to a Rails controller with strong parameters:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// const employee = { name: &amp;#34;Jake&amp;#34; };
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;updateEmployee&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;number&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;employee&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;Employee&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;axios&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;put&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;Employee&lt;/span&gt;&amp;gt;(&lt;span style="color:#e6db74"&gt;`/employees/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;employee&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;employee_params&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; params&lt;span style="color:#f92672"&gt;.&lt;/span&gt;require(&lt;span style="color:#e6db74"&gt;:employee&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;permit(&lt;span style="color:#e6db74"&gt;:name&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Note that our payload is expected under key &lt;code&gt;employee&lt;/code&gt;– but we aren&amp;rsquo;t sending
it that way. When this happens, Rails infers what goes where:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;PUT https://server.dev/employees/1 { &amp;#34;employee&amp;#34; =&amp;gt; { &amp;#34;name&amp;#34; =&amp;gt; &amp;#34;Jake&amp;#34; } }
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Notice that &lt;code&gt;name&lt;/code&gt; is in the employee object, even though I didn&amp;rsquo;t send such a
payload. This works fine until you send a parameter that&amp;rsquo;s not on the
&lt;code&gt;Employee&lt;/code&gt; model, such as a nested attribute. Then you get this:&lt;/p&gt;</description></item><item><title>Assert About Response Body in RSpec Controller Tests</title><link>https://jakeworth.com/tils/assert-about-response-body-in-rspec-controller-tests/</link><pubDate>Fri, 23 Feb 2024 15:22:30 -0500</pubDate><guid>https://jakeworth.com/tils/assert-about-response-body-in-rspec-controller-tests/</guid><description>&lt;p&gt;When testing a serialized Rails API with RSpec, a common mistake is to assert
about the response body, only to find that it&amp;rsquo;s an empty string. The controller
is controlling, the view is presenting. What&amp;rsquo;s missing?&lt;/p&gt;
&lt;p&gt;What&amp;rsquo;s missing is the view: RSpec views are stubbed by default. This is ideal for most
controller tests. Just not those asserting about serialized data.&lt;/p&gt;
&lt;p&gt;Render those views with &lt;code&gt;render_views&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;require &lt;span style="color:#e6db74"&gt;&amp;#34;rails_helper&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;RSpec&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;describe &lt;span style="color:#66d9ef"&gt;WidgetsController&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;type&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;:controller&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; render_views
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; describe &lt;span style="color:#e6db74"&gt;&amp;#34;GET index&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; it &lt;span style="color:#e6db74"&gt;&amp;#34;has a widgets related heading&amp;#34;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; get &lt;span style="color:#e6db74"&gt;:index&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; expect(response&lt;span style="color:#f92672"&gt;.&lt;/span&gt;body)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to match &lt;span style="color:#e6db74"&gt;/&amp;lt;h1&amp;gt;.*widgets/im&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Conditional Props</title><link>https://jakeworth.com/tils/conditional-props/</link><pubDate>Thu, 22 Feb 2024 11:42:56 -0500</pubDate><guid>https://jakeworth.com/tils/conditional-props/</guid><description>&lt;p&gt;Passing props conditionally a component makes sense in many situations. Imagine
a select box that receives an &lt;code&gt;isDisabled&lt;/code&gt; prop that disables the
input. Maybe we only want to set it if it&amp;rsquo;s true. For one, it&amp;rsquo;s a bit cleaner
than setting it to its default &lt;code&gt;false&lt;/code&gt; much of the time. And maybe we want to
select a certain default value in that same scenario.&lt;/p&gt;
&lt;p&gt;Enough theorizing! Here&amp;rsquo;s the code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;Select&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;options&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;itemOptions&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#a6e22e"&gt;...&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;(&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;someCondition&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;&amp;amp;&amp;amp;&lt;/span&gt; { &lt;span style="color:#a6e22e"&gt;isDisabled&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;true&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;defaultValue&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;:&lt;/span&gt; &lt;span style="color:#960050;background-color:#1e0010"&gt;[&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;itemOptions&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;[&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;0&lt;/span&gt;&lt;span style="color:#960050;background-color:#1e0010"&gt;]]&lt;/span&gt; }&lt;span style="color:#960050;background-color:#1e0010"&gt;)&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;/&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Let me explain the magic.&lt;/p&gt;</description></item><item><title>Join React Components With Comma</title><link>https://jakeworth.com/tils/join-react-components-with-comma/</link><pubDate>Thu, 22 Feb 2024 11:24:35 -0500</pubDate><guid>https://jakeworth.com/tils/join-react-components-with-comma/</guid><description>&lt;p&gt;Want to connect a list of React components with a delimiter, like a comma? Imagine a sentence of:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Link A, Link B, Link C.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;How could we programmatically achieve this in React?&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s one answer, inserting a comma before all but the first list item:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#a6e22e"&gt;items&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;((&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;index&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;React.Fragment&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;}&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {&lt;span style="color:#a6e22e"&gt;index&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;, &amp;#39;&lt;/span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;`/items/&lt;/span&gt;&lt;span style="color:#e6db74"&gt;${&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;id&lt;/span&gt;&lt;span style="color:#e6db74"&gt;}&lt;/span&gt;&lt;span style="color:#e6db74"&gt;`&lt;/span&gt;}&amp;gt;{&lt;span style="color:#a6e22e"&gt;item&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;}&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &amp;lt;/&lt;span style="color:#f92672"&gt;React.Fragment&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;))}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Lots of other good suggestions in &lt;a href="https://gist.github.com/granmoe/274c299b792b039deecfb619753ea32c"&gt;this Gist&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Append to a Write-Protected File</title><link>https://jakeworth.com/tils/append-to-a-write-protected-file/</link><pubDate>Thu, 22 Feb 2024 08:32:29 -0500</pubDate><guid>https://jakeworth.com/tils/append-to-a-write-protected-file/</guid><description>&lt;p&gt;Suppose you want to append to a file that&amp;rsquo;s write-protected and can only be
edited via &lt;code&gt;sudo&lt;/code&gt;. Is that possible? It is!&lt;/p&gt;
&lt;p&gt;A technique I discovered today is to use &lt;code&gt;tee&lt;/code&gt; with &lt;code&gt;sudo&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ cat file.txt | sudo tee -a /etc/hosts
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This lets me append the contents of &lt;code&gt;file.txt&lt;/code&gt; to the write-protected
&lt;code&gt;/etc/hosts&lt;/code&gt; file by entering my password.&lt;/p&gt;</description></item><item><title>Ignore Whitespace in a GitHub Pull Request</title><link>https://jakeworth.com/tils/ignore-whitespace-in-a-github-pull-request/</link><pubDate>Thu, 22 Feb 2024 08:30:00 -0500</pubDate><guid>https://jakeworth.com/tils/ignore-whitespace-in-a-github-pull-request/</guid><description>&lt;p&gt;Reviewing a GitHub PR on that contains a lot of whitespace changes? Extra
whitespace can make it challenging to evaluate the substance of a PR. It&amp;rsquo;s
high on my list of things that should generally &lt;a href="https://jakeworth.com/when-should-i-not-refactor/"&gt;not be refactored&lt;/a&gt;.
Ignore whitespace by adding the query parameter &lt;code&gt;?w=1&lt;/code&gt; to your diff URL.&lt;/p&gt;</description></item><item><title>Link to Headers in GitHub READMEs</title><link>https://jakeworth.com/tils/link-to-headers-in-github-readmes/</link><pubDate>Thu, 22 Feb 2024 08:30:00 -0500</pubDate><guid>https://jakeworth.com/tils/link-to-headers-in-github-readmes/</guid><description>&lt;p&gt;Anytime you add a header to a markdown file, GitHub attaches an &lt;code&gt;href&lt;/code&gt; with its
downcased name. &amp;lsquo;JavaScript&amp;rsquo; receives a link to &lt;code&gt;#javascript&lt;/code&gt;, for instance.&lt;/p&gt;
&lt;p&gt;Leverage this by adding a table of contents to your README with links to the
headers further down the document:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;### Table of Contents
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;-&lt;/span&gt; [&lt;span style="color:#f92672"&gt;Cucumber&lt;/span&gt;](&lt;span style="color:#a6e22e"&gt;#cucumber&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This will link to a header containing &amp;lsquo;Cucumber&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;h/t Josh Branchaud&lt;/p&gt;</description></item><item><title>Filter Network Requests By Status Code in DevTools</title><link>https://jakeworth.com/tils/filter-network-requests-by-status-code-in-devtools/</link><pubDate>Thu, 22 Feb 2024 08:16:35 -0500</pubDate><guid>https://jakeworth.com/tils/filter-network-requests-by-status-code-in-devtools/</guid><description>&lt;p&gt;The Chrome DevTools Network Tab is incredibly useful for frontend web
development, but it can be noisy.&lt;/p&gt;
&lt;p&gt;Perhaps you&amp;rsquo;d like to filter it down by HTTP status code? See only redirects,
so you can fix routes? Or only successful requests, so you can know what&amp;rsquo;s
working?&lt;/p&gt;
&lt;p&gt;The Network Tab supports this. Here&amp;rsquo;s a filter to just temporary redirects:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;status-code:307
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>XCode Run Hotkey</title><link>https://jakeworth.com/tils/xcode-run-hotkey/</link><pubDate>Tue, 30 Jan 2024 11:12:52 -0500</pubDate><guid>https://jakeworth.com/tils/xcode-run-hotkey/</guid><description>&lt;p&gt;&lt;code&gt;⌘ + R&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Link Externally With React Router's Link</title><link>https://jakeworth.com/tils/link-externally-with-react-routers-link/</link><pubDate>Fri, 15 Dec 2023 11:45:30 -0500</pubDate><guid>https://jakeworth.com/tils/link-externally-with-react-routers-link/</guid><description>&lt;p&gt;React Router&amp;rsquo;s &lt;code&gt;Link&lt;/code&gt; component isn&amp;rsquo;t just for internal links; it can work like
an anchor tag, too, sending users outside the application. Use &lt;code&gt;reloadDocument&lt;/code&gt;
prop to get this behavior.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;Link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;reloadDocument&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;to&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#e6db74"&gt;&amp;#39;https://reactrouter.com/en/main/components/link&amp;#39;&lt;/span&gt;}&amp;gt;&lt;span style="color:#a6e22e"&gt;Link&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;docs&lt;/span&gt;&amp;lt;/&lt;span style="color:#f92672"&gt;Link&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://reactrouter.com/en/main/components/link"&gt;docs&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Create a File With `cat`</title><link>https://jakeworth.com/tils/create-a-file-with-cat/</link><pubDate>Tue, 12 Dec 2023 13:51:16 -0500</pubDate><guid>https://jakeworth.com/tils/create-a-file-with-cat/</guid><description>&lt;p&gt;When you combine &lt;code&gt;cat&lt;/code&gt; (concatenate) with &lt;code&gt;&amp;gt;&lt;/code&gt; (output redirection),
you can create and write to a file from the command line.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ cat &amp;gt; test.txt
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Hit enter after the file name, and your terminal will wait for input. End the
file with &lt;code&gt;CTRL + D&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ cat &amp;gt; test.txt
one
two
three
$ cat test.txt
one
two
three
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;&amp;gt;&amp;gt;&lt;/code&gt; works, too; appending to the file as expected.&lt;/p&gt;</description></item><item><title>TypeScript Union Type From Array</title><link>https://jakeworth.com/tils/typescript-union-type-from-array/</link><pubDate>Mon, 11 Dec 2023 12:00:51 -0500</pubDate><guid>https://jakeworth.com/tils/typescript-union-type-from-array/</guid><description>&lt;p&gt;With the new &lt;code&gt;as const&lt;/code&gt; construct, we can derive a TypeScript union type from
a JavaScript array!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;builderSteps&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;communications&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;estimates&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;health status&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;procedures&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;] &lt;span style="color:#66d9ef"&gt;as&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;const&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;type&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;BuilderStep&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#66d9ef"&gt;typeof&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;builderSteps&lt;/span&gt;)[&lt;span style="color:#66d9ef"&gt;number&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This lets us both type a slice of state, type its updater, and build JSX
elements all from the same array, a virtuous cycle.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-tsx" data-lang="tsx"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; [&lt;span style="color:#a6e22e"&gt;step&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;setStep&lt;/span&gt;] &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;useState&lt;/span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;BuilderStep&lt;/span&gt;&amp;gt;(&lt;span style="color:#e6db74"&gt;&amp;#39;communications&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;handleStepClick&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;step&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;BuilderStep&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;setStep&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;step&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;{&lt;span style="color:#a6e22e"&gt;builderSteps&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;map&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;step&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &amp;lt;&lt;span style="color:#f92672"&gt;button&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;key&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{&lt;span style="color:#a6e22e"&gt;step&lt;/span&gt;} &lt;span style="color:#a6e22e"&gt;onClick&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;{() &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;handleStepClick&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;step&lt;/span&gt;)}&amp;gt;{&lt;span style="color:#a6e22e"&gt;step&lt;/span&gt;}&amp;lt;/&lt;span style="color:#f92672"&gt;button&lt;/span&gt;&amp;gt;)}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://www.typescriptlang.org/docs/handbook/release-notes/typescript-3-4.html#const-assertions"&gt;const assertions&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Change Timezone in Chrome DevTools</title><link>https://jakeworth.com/tils/change-timezone-in-chrome-devtools/</link><pubDate>Wed, 15 Nov 2023 15:34:21 -0800</pubDate><guid>https://jakeworth.com/tils/change-timezone-in-chrome-devtools/</guid><description>&lt;p&gt;Open Chrome DevTools, and click the three dots in the top right corner. Select &amp;lsquo;More
Tools &amp;gt; Sensors&amp;rsquo;. Under &amp;lsquo;Location&amp;rsquo;, set your timezone override.&lt;/p&gt;</description></item><item><title>Install SVGO With Reasonable Defaults, Part Two</title><link>https://jakeworth.com/tils/install-svgo-with-reasonable-defaults-part-two/</link><pubDate>Thu, 06 Apr 2023 11:04:19 -0400</pubDate><guid>https://jakeworth.com/tils/install-svgo-with-reasonable-defaults-part-two/</guid><description>&lt;p&gt;We&amp;rsquo;re back with another SVGO configuration you&amp;rsquo;ll probably want: disabling ID
minification.&lt;/p&gt;
&lt;p&gt;SVGO has a default plugin called &lt;code&gt;cleanupIds&lt;/code&gt; that takes every ID in the SVG
(e.g. &lt;code&gt;clip0_506_1332&lt;/code&gt;) and minifies it to &lt;code&gt;a&lt;/code&gt;. This works okay until there are
two different SVG&amp;rsquo;s on the page. When that happens, the ID&amp;rsquo;s become invalid and
conflicting HTML and your images don&amp;rsquo;t compose correctly.&lt;/p&gt;
&lt;p&gt;Disable this in the SVGO config file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// svgo.config.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;plugins&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;preset-default&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;overrides&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;cleanupIds&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Apply a Conditional Border Without Moving Element</title><link>https://jakeworth.com/tils/apply-a-conditional-border-without-moving-element/</link><pubDate>Fri, 24 Mar 2023 09:11:39 -0400</pubDate><guid>https://jakeworth.com/tils/apply-a-conditional-border-without-moving-element/</guid><description>&lt;p&gt;When you allow a user&amp;rsquo;s behavior to add or remove a border from an element,
that can cause the page to &amp;lsquo;jump around&amp;rsquo; as the border is added or removed. A
common example is a border around an element that is &amp;lsquo;selected&amp;rsquo;.&lt;/p&gt;
&lt;p&gt;Fix this issue by adding a transparent border around the element and giving it
color when it&amp;rsquo;s selected. No more jumps.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-scss" data-lang="scss"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;.element&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;border&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;px&lt;/span&gt; solid transparent;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;.selectedElement&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;border-color&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; $selected-color;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Apply a Patch in Reverse</title><link>https://jakeworth.com/tils/apply-a-patch-in-reverse/</link><pubDate>Fri, 24 Mar 2023 09:11:39 -0400</pubDate><guid>https://jakeworth.com/tils/apply-a-patch-in-reverse/</guid><description>&lt;p&gt;Need to undo a code change? You could revert. Or, you could apply the patch
without creating a commit. That&amp;rsquo;s what I want to do much of the time.&lt;/p&gt;
&lt;p&gt;Use &lt;code&gt;git apply&lt;/code&gt; with the &lt;code&gt;-R&lt;/code&gt; (reverse) flag:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git show 8cc13b1 | git apply -R
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;All the changes from &lt;code&gt;8cc13b1&lt;/code&gt; get applied to your working directory. In a large commit,
do this tactically by limiting to just one file or directory.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git show 8cc13b1 src/fileToRevert.ts | git apply -R
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Install SVGO With Reasonable Defaults</title><link>https://jakeworth.com/tils/install-svgo-with-reasonable-defaults/</link><pubDate>Wed, 22 Mar 2023 08:43:18 -0400</pubDate><guid>https://jakeworth.com/tils/install-svgo-with-reasonable-defaults/</guid><description>&lt;p&gt;A project I&amp;rsquo;m working on uses &lt;a href="https://github.com/svg/svgo"&gt;SVGO&lt;/a&gt; to clean and
minify SVG files. There&amp;rsquo;s one problem: SVGO by default removes the &lt;code&gt;viewBox&lt;/code&gt;
attribute, which comes embedded in the SVG&amp;rsquo;s I receive and have stylistic
meaning in my codebase.&lt;/p&gt;
&lt;p&gt;You can override this default by using an SVGO config file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;// svgo.config.js
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;module&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;exports&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;plugins&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;name&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;preset-default&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;params&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;overrides&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;removeViewBox&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; ],
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;};
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Applied like so:&lt;/p&gt;</description></item><item><title>Override Autojump's Directory Rankings</title><link>https://jakeworth.com/tils/override-autojumps-directory-rankings/</link><pubDate>Wed, 08 Mar 2023 10:12:50 -0500</pubDate><guid>https://jakeworth.com/tils/override-autojumps-directory-rankings/</guid><description>&lt;p&gt;&lt;a href="https://github.com/wting/autojump"&gt;Autojump&lt;/a&gt; is my tool of choice for
navigating directories. If I enter the following into the terminal:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ j til
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Autojump will try to guess where I want to go among directories I&amp;rsquo;ve previously
visited. It uses a database of directories and their relative rankings to do
so.&lt;/p&gt;
&lt;p&gt;But there&amp;rsquo;s a problem! These day I only want to visit &lt;code&gt;~/oss/til&lt;/code&gt;. In the past
I&amp;rsquo;ve visited &lt;code&gt;~/oss/hr-til&lt;/code&gt; and &lt;code&gt;~/oss/tilex&lt;/code&gt; hundreds of times. Autojump
always sends me there first. I don&amp;rsquo;t want that!&lt;/p&gt;</description></item><item><title>Sorting Numbers with JavaScript's sort Function</title><link>https://jakeworth.com/tils/sorting-numbers-with-javascripts-sort-function/</link><pubDate>Fri, 10 Feb 2023 10:04:55 -0500</pubDate><guid>https://jakeworth.com/tils/sorting-numbers-with-javascripts-sort-function/</guid><description>&lt;p&gt;Today in &amp;ldquo;Let JavaScript Surprise You&amp;rdquo;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;let&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;array&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;];
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;array&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;());
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;😳 The numbers are not sorted as we might expect. What&amp;rsquo;s going on here? From
Mozilla&amp;rsquo;s &lt;a href="http://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Array/sort"&gt;docs&lt;/a&gt;:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;The default sort order is ascending, built upon converting the elements into
strings, then comparing their sequences of UTF-16 code units values.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Now this sorting makes sense! Luckily, &lt;code&gt;sort&lt;/code&gt; accepts a function, so here&amp;rsquo;s the sorting
we intended:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-js" data-lang="js"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sortNumbers&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; (&lt;span style="color:#a6e22e"&gt;first&lt;/span&gt;, &lt;span style="color:#a6e22e"&gt;second&lt;/span&gt;) =&amp;gt; &lt;span style="color:#a6e22e"&gt;first&lt;/span&gt; &lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;second&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#a6e22e"&gt;console&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;log&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;array&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;sort&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;sortNumbers&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; [&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;11&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;17&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;20&lt;/span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Build a Sentence from a JavaScript Array</title><link>https://jakeworth.com/tils/build-a-sentence-from-a-javascript-array/</link><pubDate>Thu, 22 Dec 2022 09:12:08 -0500</pubDate><guid>https://jakeworth.com/tils/build-a-sentence-from-a-javascript-array/</guid><description>&lt;p&gt;Have you ever wanted to take a JavaScript array of strings and turn them into a
sentence? Here&amp;rsquo;s how you do that.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-javascript" data-lang="javascript"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;toLearn&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; [
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;object-oriented programming&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;frontend engineering&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;testing&amp;#39;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;]
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;sentence&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;new&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Intl&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;ListFormat&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;format&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;toLearn&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;object-oriented programming, frontend engineering, and testing&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;ListFormat&lt;/code&gt; takes &lt;a href="https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl/ListFormat"&gt;options&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;This has cross-browser support! The days of building a &amp;rsquo;to sentence&amp;rsquo; function
in JavaScript are over.&lt;/p&gt;</description></item><item><title>Zoom and Scroll in Figma</title><link>https://jakeworth.com/tils/zoom-and-scroll-in-figma/</link><pubDate>Tue, 20 Dec 2022 11:22:34 -0500</pubDate><guid>https://jakeworth.com/tils/zoom-and-scroll-in-figma/</guid><description>&lt;p&gt;When viewing a Figma design file, you can zoom in/out with &lt;code&gt;CMD&lt;/code&gt; and up/down on
a trackpad or magic mouse.&lt;/p&gt;
&lt;p&gt;Scroll left or right with one-finger swipe left or right.&lt;/p&gt;
&lt;p&gt;Zoom and scroll; along with adding comments and copying CSS, that&amp;rsquo;s most of
what I do in Figma.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m sure that these commands are useful in many other settings, but I find them
especially valuable in a Figma file, which can feel otherwise challenging for
me to navigate.&lt;/p&gt;</description></item><item><title>Source Tmux Config</title><link>https://jakeworth.com/tils/source-tmux-config/</link><pubDate>Fri, 26 Aug 2022 17:56:33 -0400</pubDate><guid>https://jakeworth.com/tils/source-tmux-config/</guid><description>&lt;p&gt;You&amp;rsquo;ve been iterating on your Tmux configuration file, and now you want to your
configs in action without closing the program. But how?&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s the command to source an updated &lt;code&gt;tmux.conf&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ tmux source-file tmux.conf
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Tmux Copy Mode</title><link>https://jakeworth.com/tils/tmux-copy-mode/</link><pubDate>Fri, 26 Aug 2022 17:54:55 -0400</pubDate><guid>https://jakeworth.com/tils/tmux-copy-mode/</guid><description>&lt;p&gt;Last week we encountered a breaking change in our Tmux configuration, and briefly lost the ability to scroll with the mouse. It became an opportunity to re-learn Tmux&amp;rsquo;s copy mode, and liberate ourselves from the mouse a little more.&lt;/p&gt;
&lt;p&gt;Enter copy mode with &lt;code&gt;&amp;lt;prefix&amp;gt; [&lt;/code&gt;. From here, you can navigate with standard Vim commands.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ctrl-u&lt;/code&gt; moves you a half-page up, perfect for wading through test failure backtraces.&lt;/p&gt;</description></item><item><title>Preserve Whitespace in CSS</title><link>https://jakeworth.com/tils/preserve-whitespace-in-css/</link><pubDate>Wed, 03 Aug 2022 10:30:10 -0400</pubDate><guid>https://jakeworth.com/tils/preserve-whitespace-in-css/</guid><description>&lt;p&gt;Let&amp;rsquo;s say you have a string evaluated into a HTML template that contains
newlines, like &lt;code&gt;&amp;quot;getting\n\things\ndone&amp;quot;&lt;/code&gt; and you want those newlines to be
reflected in the presentation. Like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;getting
things
done
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can solve this with the following CSS on the string&amp;rsquo;s containing element:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;white-space&lt;/span&gt;&lt;span style="color:#f92672"&gt;:&lt;/span&gt; &lt;span style="color:#f92672"&gt;pre-wrap&lt;/span&gt;&lt;span style="color:#f92672"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With &lt;code&gt;pre-wrap&lt;/code&gt;, &amp;ldquo;[s]equences of white space are preserved. Lines are broken at
newline characters, at [breaks] and as necessary to fill line boxes.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://developer.mozilla.org/en-US/docs/Web/CSS/white-space"&gt;white-space docs&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Validate CircleCI Configuration Locally</title><link>https://jakeworth.com/tils/validate-circleci-configuration-locally/</link><pubDate>Wed, 22 Jun 2022 11:18:13 -0400</pubDate><guid>https://jakeworth.com/tils/validate-circleci-configuration-locally/</guid><description>&lt;p&gt;The local environment is a great place to iterate on a CircleCI configuration.
You&amp;rsquo;ll catch errors faster than pushing to CI, and help drive a fast, iterative
configuration process.&lt;/p&gt;
&lt;p&gt;Install the &lt;a href="https://circleci.com/docs/2.0/local-cli"&gt;CircleCI CLI&lt;/a&gt; via Homebrew (or any package manager of your choice):&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ brew install circleci
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, in the same directory as your &lt;code&gt;.circleci/config.yml&lt;/code&gt;, run:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ circleci config validate
# Config file at .circleci/config.yml is valid
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Force ASDF Reshim</title><link>https://jakeworth.com/tils/force-asdf-reshim/</link><pubDate>Tue, 21 Jun 2022 09:49:59 -0400</pubDate><guid>https://jakeworth.com/tils/force-asdf-reshim/</guid><description>&lt;p&gt;When I upgrade ASDF, I sometimes get an error like this when I try to run a
command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/Users/jakeworth/.asdf/shims/jq: line 3:
/usr/local/Cellar/asdf/0.9.0/libexec/bin/asdf:
No such file or directory
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The issue is that I&amp;rsquo;ve upgraded ADSF to v0.10.2, but the jq shim doesn&amp;rsquo;t know
that and can&amp;rsquo;t find it in a directory called &amp;ldquo;0.9.0&amp;rdquo;. This issue persists even
after running &lt;code&gt;asdf reshim&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;My solution is to force ASDF to rebuild shims directory by renaming it. A
rename lets me get back to where I am now, in case I need to.&lt;/p&gt;</description></item><item><title>Select First Spell Suggestion</title><link>https://jakeworth.com/tils/select-first-spell-suggestion/</link><pubDate>Tue, 14 Jun 2022 11:58:15 -0400</pubDate><guid>https://jakeworth.com/tils/select-first-spell-suggestion/</guid><description>&lt;p&gt;I use Vim&amp;rsquo;s spell feature when writing blog posts. Very often, the first
suggestion it makes is the one that I choose. Consider a word like &amp;lsquo;Rubysit.&amp;rsquo;
My dictionary contains the word &amp;lsquo;Rubyist&amp;rsquo; (naturally) and that&amp;rsquo;s what Vim spell
is going to suggest to me first. For transposition errors like this I&amp;rsquo;d like to
skip the word picker when possible.&lt;/p&gt;
&lt;p&gt;To automatically choose the first suggestion, in normal mode put your cursor
over the word and type &lt;code&gt;1z=&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Hide Bookmarks Bar in Chrome</title><link>https://jakeworth.com/tils/hide-bookmarks-bar-in-chrome/</link><pubDate>Mon, 13 Jun 2022 14:24:29 -0400</pubDate><guid>https://jakeworth.com/tils/hide-bookmarks-bar-in-chrome/</guid><description>&lt;p&gt;To hide the bookmarks bar in Google Chrome:&lt;/p&gt;
&lt;p&gt;Press CMD + SHIFT + B on Mac&lt;br&gt;
Press CTRL + SHIFT + B on Windows&lt;/p&gt;
&lt;p&gt;This shortcut toggles the bookmarks bar on or off.&lt;/p&gt;</description></item><item><title>Ctags Dotfiles</title><link>https://jakeworth.com/tils/ctags-dotfiles/</link><pubDate>Fri, 18 Mar 2022 12:11:25 -0400</pubDate><guid>https://jakeworth.com/tils/ctags-dotfiles/</guid><description>&lt;p&gt;Something I took for granted at Hashrocket was the file that configures
&lt;a href="http://ctags.sourceforge.net/"&gt;Exhuberant Ctags&lt;/a&gt;. Without configuration,
recursive tag generation will tag many things and cause problems. overindex
badly.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how you configure Ctags to ignore things:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;/ctags.cnf (on MSDOS, MSWindows only)
/etc/ctags.conf
/usr/local/etc/ctags.conf
$HOME/.ctags
$HOME/ctags.cnf (on MSDOS, MSWindows only)
.ctags
ctags.cnf (on MSDOS, MSWindows only)
If any of these configuration files exist, each will be expected to contain a
set of default options which are read in the order listed when ctags starts,
but before the CTAGS environment variable is read or any command line options
are read. This makes it possible to set up site-wide, personal or project-level
defaults.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Here&amp;rsquo;s the &lt;code&gt;head&lt;/code&gt; of my root &lt;code&gt;.ctags&lt;/code&gt;, which even this far in is excluding a
lot:&lt;/p&gt;</description></item><item><title>Jump to N Percent of a File</title><link>https://jakeworth.com/tils/jump-to-n-percent-of-a-file/</link><pubDate>Sun, 23 Jan 2022 16:54:36 -0500</pubDate><guid>https://jakeworth.com/tils/jump-to-n-percent-of-a-file/</guid><description>&lt;p&gt;From normal mode, &lt;code&gt;N%&lt;/code&gt; will jump you to that percentage of the file. So &lt;code&gt;50%&lt;/code&gt;
jumps to halfway through the file.&lt;/p&gt;</description></item><item><title>Find Stale Gems</title><link>https://jakeworth.com/tils/find-stale-gems/</link><pubDate>Tue, 16 Nov 2021 14:19:45 -0500</pubDate><guid>https://jakeworth.com/tils/find-stale-gems/</guid><description>&lt;p&gt;Unused dependencies are bad: they increase the size of your project, slow down
processes, require maintenance, and send incorrect messages to fellow
developers about what&amp;rsquo;s important.&lt;/p&gt;
&lt;p&gt;To get find unused dependencies in Ruby, I&amp;rsquo;ve been using &lt;code&gt;gem stale&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;gem stale
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;gem stale&lt;/code&gt; list gems along with most recent access times. If the last access
time was the day you set up the app, that gem is a candidate for removal.&lt;/p&gt;</description></item><item><title>Save Size Change to iTerm Profile</title><link>https://jakeworth.com/tils/save-size-changes-to-iterm-profile/</link><pubDate>Sat, 13 Nov 2021 13:35:21 -0500</pubDate><guid>https://jakeworth.com/tils/save-size-changes-to-iterm-profile/</guid><description>&lt;p&gt;The longer I program (ahem), the bigger I want my terminal fonts. I think most
programmers should be using a bigger font than they are. Complicating matters,
the standard font for iTerm is miniscule on a computer monitor.&lt;/p&gt;
&lt;p&gt;Today I discovered iTerm&amp;rsquo;s &amp;lsquo;View &amp;gt; Size Changes Update Profile&amp;rsquo; feature. When
enabled, changes to your font size via &lt;code&gt;⌘ +&lt;/code&gt; and &lt;code&gt;⌘ -&lt;/code&gt; will be applied to your
iTerm profile. The next time you open iTerm, the new font size will persist.&lt;/p&gt;</description></item><item><title>Man pages in Vim</title><link>https://jakeworth.com/tils/man-pages-in-vim/</link><pubDate>Thu, 11 Nov 2021 16:47:07 -0500</pubDate><guid>https://jakeworth.com/tils/man-pages-in-vim/</guid><description>&lt;p&gt;Hit &lt;code&gt;K&lt;/code&gt; on a keyword, and Vim looks up the program under the keyword. It&amp;rsquo;s a
bit jarring because Vim appears to shell out from your buffer to show the
definition.&lt;/p&gt;
&lt;p&gt;To see that man page &lt;em&gt;in&lt;/em&gt; Vim, load the &lt;code&gt;man.vim&lt;/code&gt; plugin from command mode or
in your &lt;code&gt;.vimrc&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:runtime! ftplugin/man.vim
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Now, you can read man pages as a Vim buffer:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:Man curl
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Why Is It Called PostgreSQL?</title><link>https://jakeworth.com/tils/history-of-the-postgresql-name/</link><pubDate>Wed, 10 Nov 2021 11:04:17 -0500</pubDate><guid>https://jakeworth.com/tils/history-of-the-postgresql-name/</guid><description>&lt;p&gt;PostgreSQL was originally named &amp;ldquo;POSTGRES&amp;rdquo;— all caps. The name was chosen
because it was the successor (&amp;ldquo;post-&amp;rdquo;) to the &amp;ldquo;Ingres&amp;rdquo; database. As the system
adopted SQL standards and features, the &amp;ldquo;ql&amp;rdquo; as added and capitalization
refined.&lt;/p&gt;</description></item><item><title>Ignore Rubocop Block Length Lint in RSpec</title><link>https://jakeworth.com/tils/ignore-rubocop-block-length-lint-in-rspec/</link><pubDate>Tue, 09 Nov 2021 18:12:52 -0500</pubDate><guid>https://jakeworth.com/tils/ignore-rubocop-block-length-lint-in-rspec/</guid><description>&lt;p&gt;Linters are great, except when they aren&amp;rsquo;t. One example is Rubocop&amp;rsquo;s
&lt;code&gt;BlockLength&lt;/code&gt; lint. For example, I don&amp;rsquo;t care if my RSpec &lt;code&gt;describe&lt;/code&gt; and
&lt;code&gt;context&lt;/code&gt; blocks are too long. Nontrivial test blocks will never be short
enough to match a reasonable rule about blocks.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;ve disabled this lint for these blocks with Rubocop&amp;rsquo;s configuration file:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# .rubocop.yml
Metrics/BlockLength:
IgnoredMethods: [&amp;#39;context&amp;#39;, &amp;#39;describe&amp;#39;]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Opting out of just these blocks lets me enforce this rule everywhere else.&lt;/p&gt;</description></item><item><title>Object ID</title><link>https://jakeworth.com/tils/object-id/</link><pubDate>Mon, 08 Nov 2021 09:51:01 -0500</pubDate><guid>https://jakeworth.com/tils/object-id/</guid><description>&lt;p&gt;Today I learned about the method &lt;code&gt;__id__&lt;/code&gt;, aliased &lt;code&gt;object_id&lt;/code&gt;, in Ruby. It
returns a unique integer identifier for any Ruby object.&lt;/p&gt;
&lt;p&gt;A few examples:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Object&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;new&lt;span style="color:#f92672"&gt;.&lt;/span&gt;object_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;7024702983434&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;jake&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;jake&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; name&lt;span style="color:#f92672"&gt;.&lt;/span&gt;object_id &lt;span style="color:#f92672"&gt;==&lt;/span&gt; name&lt;span style="color:#f92672"&gt;.&lt;/span&gt;object_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;thawed&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;object_id &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;thawed&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;object_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;frozen&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;freeze&lt;span style="color:#f92672"&gt;.&lt;/span&gt;object_id &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;frozen&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;freeze&lt;span style="color:#f92672"&gt;.&lt;/span&gt;object_id
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I&amp;rsquo;ve never used this method in practice, but I hope to someday.&lt;/p&gt;</description></item><item><title>Autojump and Open</title><link>https://jakeworth.com/tils/autojump-and-open/</link><pubDate>Sat, 06 Nov 2021 13:39:32 -0400</pubDate><guid>https://jakeworth.com/tils/autojump-and-open/</guid><description>&lt;p&gt;I love &lt;a href="https://github.com/wting/autojump"&gt;autojump&lt;/a&gt;. I use it because I think
that remembering my location in a directory structure relative to other
directories, so I can navigate with &lt;code&gt;cd&lt;/code&gt;, is mental energy I could be using for
something else.&lt;/p&gt;
&lt;p&gt;Today I learned that autojump has a &lt;code&gt;jo&lt;/code&gt; command, which &lt;em&gt;jumps&lt;/em&gt; to a directory
and &lt;em&gt;opens&lt;/em&gt; it in your file explorer.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;jo Desktop
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This might be a throwaway lesson if I wasn&amp;rsquo;t regularly sidetracked by the MacOS
file explorer. Finding a file using the file explorer is a routine operation I
have yet to do fluidly on a Mac. This helps!&lt;/p&gt;</description></item><item><title>Force with Lease</title><link>https://jakeworth.com/tils/force-with-lease/</link><pubDate>Fri, 05 Nov 2021 21:21:44 -0400</pubDate><guid>https://jakeworth.com/tils/force-with-lease/</guid><description>&lt;p&gt;When I rebase, I force-push altered history using the flag &lt;code&gt;--force-with-lease&lt;/code&gt;
instead of the commonly-used &lt;code&gt;--force&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git push --force-with-lease
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;But why? This is a TIL for me because I&amp;rsquo;ve used this command for years without
reading the docs.&lt;/p&gt;
&lt;p&gt;Take it away, docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;This option allows you to say that you expect the history you are updating is
what you rebased and want to replace. If the remote ref still points at the
commit you specified, you can be sure that no other people did anything to
the ref.&lt;/p&gt;</description></item><item><title>`group_by` with default</title><link>https://jakeworth.com/tils/group-by-with-default/</link><pubDate>Fri, 05 Nov 2021 08:16:02 -0400</pubDate><guid>https://jakeworth.com/tils/group-by-with-default/</guid><description>&lt;p&gt;Here&amp;rsquo;s some code that made me do a double take.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;something &lt;span style="color:#f92672"&gt;=&lt;/span&gt; items&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It&amp;rsquo;s that &lt;code&gt;[nil]&lt;/code&gt;. What&amp;rsquo;s going on here?&lt;/p&gt;
&lt;p&gt;It turns out that &lt;code&gt;items&lt;/code&gt; is the return of a call to Ruby&amp;rsquo;s &lt;code&gt;group_by&lt;/code&gt;.
&lt;code&gt;group_by&lt;/code&gt; groups by whatever the block evaluates to, including &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e6db74"&gt;shipping&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;fedex&amp;#39;&lt;/span&gt;, id: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { &lt;span style="color:#e6db74"&gt;shipping&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;fedex&amp;#39;&lt;/span&gt;, id: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; { id: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;].&lt;/span&gt;group_by { &lt;span style="color:#f92672"&gt;|&lt;/span&gt;item&lt;span style="color:#f92672"&gt;|&lt;/span&gt; item&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;:shipping&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;fedex&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;{ &lt;span style="color:#e6db74"&gt;shipping&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;fedex&amp;#39;&lt;/span&gt;, id: &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; }, { &lt;span style="color:#e6db74"&gt;shipping&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;fedex&amp;#39;&lt;/span&gt;, id: &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; }&lt;span style="color:#f92672"&gt;]&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;{ id: &lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; }&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Hence the key &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Jira Actions Menu</title><link>https://jakeworth.com/tils/jira-actions-menu/</link><pubDate>Mon, 01 Nov 2021 14:21:29 -0400</pubDate><guid>https://jakeworth.com/tils/jira-actions-menu/</guid><description>&lt;p&gt;Jira has a hidden ticket &amp;lsquo;Actions menu&amp;rsquo; that is really helpful.&lt;/p&gt;
&lt;p&gt;When a Jira ticket is in focus, type &lt;code&gt;.&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This opens a searchable menu with &amp;lsquo;Issue actions&amp;rsquo; (&amp;lsquo;Attach&amp;rsquo;, &amp;lsquo;Link Issue&amp;rsquo;,
etc.) and &amp;lsquo;Workflow&amp;rsquo; state advancements (&amp;lsquo;To Do&amp;rsquo;, &amp;lsquo;Close&amp;rsquo;, etc.). Almost any
action you&amp;rsquo;d want to take on a ticket is there.&lt;/p&gt;</description></item><item><title>Turn off Autoformatter for New Features</title><link>https://jakeworth.com/tils/turn-off-autoformatter-for-new-features/</link><pubDate>Wed, 22 Sep 2021 12:17:38 -0400</pubDate><guid>https://jakeworth.com/tils/turn-off-autoformatter-for-new-features/</guid><description>&lt;p&gt;When developing a new feature in a brownfield app that hasn&amp;rsquo;t been subject to
consistent autoformatter treatment, turn off your autoformatter.&lt;/p&gt;
&lt;p&gt;Autoformatting is great. I advocate for it. But it can be distracting when
trying to read through your new work. The hard-won changes you make get lost in
the mix of automated changes. Once you&amp;rsquo;ve got the feature working, turn on the
autoformatter and get that automatic quality.&lt;/p&gt;
&lt;p&gt;This is a pretty niche piece of advice, but it helped me today.&lt;/p&gt;</description></item><item><title>App Store Delays</title><link>https://jakeworth.com/tils/app-store-delays/</link><pubDate>Thu, 02 Sep 2021 13:51:03 -0400</pubDate><guid>https://jakeworth.com/tils/app-store-delays/</guid><description>&lt;p&gt;Here&amp;rsquo;s an observation from a month of developing for iOS. There can be a delay
on any action taken in the App Store Connect console that you should plan for.&lt;/p&gt;</description></item><item><title>Clear iOS Mobile Dependencies</title><link>https://jakeworth.com/tils/clear-ios-mobile-dependencies/</link><pubDate>Thu, 02 Sep 2021 11:32:04 -0400</pubDate><guid>https://jakeworth.com/tils/clear-ios-mobile-dependencies/</guid><description>&lt;p&gt;When working on a React Native app on the iOS side, switching between branches
with different dependencies can wreak havoc on your development environment. To
ensure they&amp;rsquo;re you&amp;rsquo;re running the right libraries, blow everything away and
start over:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;rm -rf node_modules &amp;amp;&amp;amp; yarn &amp;amp;&amp;amp; (cd ios &amp;amp;&amp;amp; pod deintegrate &amp;amp;&amp;amp; pod install)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Replace &lt;code&gt;yarn&lt;/code&gt; with &lt;code&gt;npm install&lt;/code&gt; if you&amp;rsquo;re using NPM.&lt;/p&gt;</description></item><item><title>Clear React Router's Location State</title><link>https://jakeworth.com/tils/clear-react-routers-location-state-from-the-console/</link><pubDate>Thu, 02 Sep 2021 11:32:04 -0400</pubDate><guid>https://jakeworth.com/tils/clear-react-routers-location-state-from-the-console/</guid><description>&lt;p&gt;The return of React Router&amp;rsquo;s &lt;code&gt;useLocation&lt;/code&gt; hook has a key called &lt;code&gt;state&lt;/code&gt; which
contains values passed during a redirect or navigation. But where is that state
stored by the browser, and how do we clear it?&lt;/p&gt;</description></item><item><title>Scroll on XCode Simulator</title><link>https://jakeworth.com/tils/scroll-on-xcode-simulator/</link><pubDate>Wed, 25 Aug 2021 16:46:48 -0400</pubDate><guid>https://jakeworth.com/tils/scroll-on-xcode-simulator/</guid><description>&lt;p&gt;To get mobile scroll behavior on the XCode Simulator, inside the simulator
window you must left click, then scroll.&lt;/p&gt;</description></item><item><title>Highlighted Routes Searching</title><link>https://jakeworth.com/tils/highlighted-routes-searching/</link><pubDate>Tue, 24 Aug 2021 14:14:40 -0400</pubDate><guid>https://jakeworth.com/tils/highlighted-routes-searching/</guid><description>&lt;p&gt;On a non-trivial Rails app, the output from &lt;code&gt;rake routes&lt;/code&gt; will be huge. Many
people develop a reflex for searching through this output via something like:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ rake routes | grep &amp;#34;&amp;lt;string&amp;gt;&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which filters the output to matches on the string. I&amp;rsquo;d like to suggest a better option: use
a command-line search tool that highlights the output! Here&amp;rsquo;s that same command with RipGrep:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ rake routes | rg &amp;#34;&amp;lt;string&amp;gt;&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The results are the same (although much faster 😈), but even better is that
that each match will be colorized. It&amp;rsquo;s bright red in my terminal. The
colorizing makes the matches much easier to interpret.&lt;/p&gt;</description></item><item><title>React Native Shake</title><link>https://jakeworth.com/tils/react-native-shake/</link><pubDate>Fri, 13 Aug 2021 14:37:36 -0400</pubDate><guid>https://jakeworth.com/tils/react-native-shake/</guid><description>&lt;p&gt;The &amp;lsquo;shake&amp;rsquo; is an important React Native feature; it opens the In-App Developer
Menu. This menu lets you reload, open the inspector, monitor performance, and
more. To &amp;lsquo;shake&amp;rsquo; your simulated device, press &lt;code&gt;^ ⌘ Z&lt;/code&gt;. An alternative hotkey is
&lt;code&gt;⌘ D&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>TestFlight Downloads Latest Build</title><link>https://jakeworth.com/tils/testflight-downloads-latest-build/</link><pubDate>Fri, 13 Aug 2021 12:17:08 -0400</pubDate><guid>https://jakeworth.com/tils/testflight-downloads-latest-build/</guid><description>&lt;p&gt;When you push an iOS build to TestFlight, what&amp;rsquo;s the experience for your
testers? Do they need to opt-in to test the latest build?&lt;/p&gt;
&lt;p&gt;Speaking anecdotally as person who has pushed a build and plans to test it
today, when you add that build to your test group, it is automatically
downloaded as the default for each of your testers, replacing the previous
build. You can visit the TestFlight app on your phone to see the apps you can
test. The latest build (build number, an integer, not the SemVer version)
should be automatically downloaded to your device.&lt;/p&gt;</description></item><item><title>fields_for exclude ID</title><link>https://jakeworth.com/tils/fields-for-exclude-id/</link><pubDate>Thu, 12 Aug 2021 09:47:32 -0400</pubDate><guid>https://jakeworth.com/tils/fields-for-exclude-id/</guid><description>&lt;p&gt;Rails&amp;rsquo; &lt;code&gt;fields_for&lt;/code&gt; helper inserts a hidden ID field into your form. This is
generally helpful, because you&amp;rsquo;ll want that information when you&amp;rsquo;re updating
the record. But what if you don&amp;rsquo;t?&lt;/p&gt;
&lt;p&gt;This is the scenario I encountered today: a &amp;lsquo;read-only&amp;rsquo; form nested inside a
&lt;code&gt;fields_for&lt;/code&gt; helper, with no inputs. It almost worked: unfortunately, due to
the default ID-inserting behavior of &lt;code&gt;fields_for&lt;/code&gt;, there was a &lt;em&gt;hidden&lt;/em&gt; ID
input. It was getting submitted with the rest of the form and breaking things.&lt;/p&gt;</description></item><item><title>Use Display None</title><link>https://jakeworth.com/tils/use-display-none/</link><pubDate>Fri, 06 Aug 2021 09:30:59 -0400</pubDate><guid>https://jakeworth.com/tils/use-display-none/</guid><description>&lt;p&gt;I recently delivered a form that was hidden via CSS, using the BassCSS
&lt;a href="https://basscss.com/#accessible-hide"&gt;&lt;code&gt;hide&lt;/code&gt;&lt;/a&gt; class, and encountered an issue:
iOS customers&amp;rsquo; browsers were and trying to autofill this hidden form with their
saved passwords. What was going on here?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;hide&lt;/code&gt; it imparts these styles on its target in my Chrome:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;.hide {
position: absolute !important;
height: 1px;
width: 1px;
overflow: hidden;
clip: rect(1px,1px,1px,1px);
}
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This worked visually, but it didn&amp;rsquo;t hide the form from iOS. Browsing the
BassCSS docs, I learned that this is an &amp;lsquo;accessible&amp;rsquo; hide, meant to visually
hide an element from view but keep it available to screen readers. No wonder
iOS was confused.&lt;/p&gt;</description></item><item><title>Edit in Pry</title><link>https://jakeworth.com/tils/edit-in-pry/</link><pubDate>Tue, 03 Aug 2021 16:30:47 -0400</pubDate><guid>https://jakeworth.com/tils/edit-in-pry/</guid><description>&lt;p&gt;Here&amp;rsquo;s a scenario: you&amp;rsquo;re hacking on Ruby code in &lt;code&gt;pry&lt;/code&gt;, and it&amp;rsquo;s a mess.
Blocks chained on blocks, variables named &lt;code&gt;a&lt;/code&gt; and &lt;code&gt;other_one&lt;/code&gt;, assignments to
&lt;code&gt;_&lt;/code&gt;. You can understand it, but nobody else can, and one extra &lt;code&gt;}&lt;/code&gt; breaks
everything.&lt;/p&gt;
&lt;p&gt;The solution is the &lt;code&gt;edit&lt;/code&gt; command. Typing &lt;code&gt;edit&lt;/code&gt; in &lt;code&gt;pry&lt;/code&gt; loads the current
buffer into your editor of choice. Jump in there and turn those inline blocks
into &lt;code&gt;do&lt;/code&gt;/&lt;code&gt;end&lt;/code&gt;, assign some variables, write a method: iterate on some quality
code in the comfortable, predictable setting of your text editor.&lt;/p&gt;</description></item><item><title>Command Line Subshell</title><link>https://jakeworth.com/tils/command-line-subshell/</link><pubDate>Mon, 02 Aug 2021 11:34:14 -0400</pubDate><guid>https://jakeworth.com/tils/command-line-subshell/</guid><description>&lt;p&gt;When chaining commands in the terminal, you may need to do things that affect
the shell&amp;rsquo;s environment, like change directories. Here&amp;rsquo;s an example:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ yarn install &amp;amp;&amp;amp; cd ios &amp;amp;&amp;amp; pod install &amp;amp;&amp;amp; cd .. &amp;amp;&amp;amp; yarn build
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These &lt;code&gt;cd&lt;/code&gt;&amp;rsquo;s can clutter up a script, and they&amp;rsquo;re incidental. My solution is to
use a subshell (here&amp;rsquo;s the explanation from &lt;code&gt;man bash&lt;/code&gt;):&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;(list) list is executed in a subshell environment (see COMMAND EXECUTION ENVIRONMENT below). Variable
assignments and builtin commands that affect the shell&amp;rsquo;s environment do not remain in effect
after the command completes. The return status is the exit status of list.&lt;/p&gt;</description></item><item><title>Hash Equality</title><link>https://jakeworth.com/tils/hash-equality/</link><pubDate>Wed, 05 May 2021 09:32:46 -0400</pubDate><guid>https://jakeworth.com/tils/hash-equality/</guid><description>&lt;p&gt;Ruby&amp;rsquo;s &amp;lsquo;principle of least surprise&amp;rsquo; strikes me again. From the docs:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Equality— Two hashes are equal if they each contain the same number of keys
and if each key-value pair is equal to (according to &lt;code&gt;Object#==&lt;/code&gt;) the
corresponding elements in the other hash.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;An example:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;hash = { 7 =&amp;gt; 35, &amp;#34;c&amp;#34; =&amp;gt; 2, &amp;#34;a&amp;#34; =&amp;gt; 1 }
doppelganger = { &amp;#34;a&amp;#34; =&amp;gt; 1, &amp;#34;c&amp;#34; =&amp;gt; 2, 7 =&amp;gt; 35 }
hash == doppelganger #=&amp;gt; true
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Show Proc Source Location</title><link>https://jakeworth.com/tils/show-proc-source-location/</link><pubDate>Wed, 28 Apr 2021 17:02:11 -0400</pubDate><guid>https://jakeworth.com/tils/show-proc-source-location/</guid><description>&lt;p&gt;Today I was investigating a Ruby Proc created in a gem, and I wanted to know
how it was defined. Other than reading source code, there doesn&amp;rsquo;t seem to be a
good way to do this! Prove me wrong.&lt;/p&gt;
&lt;p&gt;We can get close by using Ruby&amp;rsquo;s &lt;code&gt;#source_location&lt;/code&gt; function on &lt;code&gt;Proc&lt;/code&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;some_proc.source_location
=&amp;gt; [&amp;#34;/gems/2.4.0/bundler/gems/spree/core/app/models/spree/order.rb&amp;#34;, 34]
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This command shows us the line where Proc is defined. Go there to continue
source-diving.&lt;/p&gt;</description></item><item><title>Chrome SameSite Updates</title><link>https://jakeworth.com/tils/chrome-samesite-updates/</link><pubDate>Fri, 23 Apr 2021 16:26:58 -0400</pubDate><guid>https://jakeworth.com/tils/chrome-samesite-updates/</guid><description>&lt;p&gt;Yesterday I wrote about &lt;a href="browsers/chrome-flags.md"&gt;Chrome Flags&lt;/a&gt;; today I&amp;rsquo;ll
explain why.&lt;/p&gt;
&lt;p&gt;Chrome is currently rolling out sweeping changes to how it handles cookies. I
learned a &lt;em&gt;lot&lt;/em&gt; about it this week. To summarize, cookies that don&amp;rsquo;t specify a
&lt;code&gt;SameSite&lt;/code&gt; attribute will be treated as &lt;code&gt;SameSite=Lax&lt;/code&gt; by Chrome starting with
version 91. Ask for those cookies from a different URL, and Chrome won&amp;rsquo;t share
them. This means that cookies intended for third-party or cross-site sharing
must specify &lt;code&gt;SameSite=None&lt;/code&gt; and &lt;code&gt;Secure&lt;/code&gt;. You can opt into this behavior today
with the aforementioned flags.&lt;/p&gt;</description></item><item><title>Chrome Flags</title><link>https://jakeworth.com/tils/chrome-flags/</link><pubDate>Thu, 22 Apr 2021 22:00:13 -0400</pubDate><guid>https://jakeworth.com/tils/chrome-flags/</guid><description>&lt;p&gt;Chrome is making changes all time time; ignore them at your peril. Today I
discovered Chrome&amp;rsquo;s Flags menu, which lets you opt-in early to features that
may soon be the default. Explore it at:&lt;/p&gt;
&lt;p&gt;chrome://flags/&lt;/p&gt;</description></item><item><title>Date Input Tag</title><link>https://jakeworth.com/tils/date-input-tag/</link><pubDate>Thu, 22 Apr 2021 22:00:13 -0400</pubDate><guid>https://jakeworth.com/tils/date-input-tag/</guid><description>&lt;p&gt;The HTML date input tag allows you to request dates in a web form.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;input&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;type&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;date&amp;#34;&lt;/span&gt;&amp;gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This tag is more semantic for date input than text, and provides a side benefit: Google Chrome will automatically display a calendar selector on the page.&lt;/p&gt;</description></item><item><title>Override Vim's Filetype</title><link>https://jakeworth.com/tils/override-vims-filetype/</link><pubDate>Thu, 22 Apr 2021 13:30:27 -0400</pubDate><guid>https://jakeworth.com/tils/override-vims-filetype/</guid><description>&lt;p&gt;Vim&amp;rsquo;s filetype auto-detection is great for effortless syntax highlighting, but
what if a certain kind of file (i.e. Ruby) contains lots of another kind of
code (i.e. SQL)? The Ruby code will be highlighted and readable, the SQL a
large monochrome blob. Hard to read and reason about. We can do better!&lt;/p&gt;
&lt;p&gt;Override the automatic assignment with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:set ft=sql
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This command with no assignment returns the current setting:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:set ft
filetype=lua
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;We can easily revert to the auto-detected extension as needed.&lt;/p&gt;</description></item><item><title>Steps Within Steps</title><link>https://jakeworth.com/tils/steps-within-steps/</link><pubDate>Wed, 21 Apr 2021 16:51:29 -0400</pubDate><guid>https://jakeworth.com/tils/steps-within-steps/</guid><description>&lt;p&gt;Cucumber step definitions are useful for explaining in detail the actions a user might take on your site. But after a while, they become repetitive. Certain sequences of steps, like a user signing in, happen frequently in a robust test suite. We should not have to repeat them all every time we build a feature.&lt;/p&gt;
&lt;p&gt;One solution is calling several steps from within another step:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Given&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;I am a signed in developer&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; steps &lt;span style="color:#e6db74"&gt;%Q{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Given I am a developer with credentials
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; And I see the homepage
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; When I click sign in
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Then I see the signin page
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; When I enter my credentials
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; And I click the sign in button
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; Then I see my username in the upper right
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt; }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you assert the topmost &lt;code&gt;Given&lt;/code&gt;, all steps in the block will be interpolated and called. You still get the confidence of a rigorous test, but with a more concise declaration.&lt;/p&gt;</description></item><item><title>Directional Commands</title><link>https://jakeworth.com/tils/directional-commands/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/directional-commands/</guid><description>&lt;p&gt;You can move the cursor without arrow keys. Here is the keyboard equivalent for each.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Up (&amp;lsquo;previous&amp;rsquo;): &lt;code&gt;CTRL + P&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Down (&amp;rsquo;next&amp;rsquo;): &lt;code&gt;CTRL + N&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Left (&amp;lsquo;back&amp;rsquo;): &lt;code&gt;CTRL + B&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Right (&amp;lsquo;forward&amp;rsquo;): &lt;code&gt;CTRL + F&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Mapping &lt;code&gt;caps lock&lt;/code&gt; to &lt;code&gt;CTRL&lt;/code&gt; makes these combinations very accessible.&lt;/p&gt;</description></item><item><title>Finding Getters</title><link>https://jakeworth.com/tils/finding-getters/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/finding-getters/</guid><description>&lt;p&gt;After writing the other day about why you &lt;a href="http://til.hashrocket.com/posts/7d6b8eb8d3-accessor-performance-gap"&gt;might not want to use simple getters&lt;/a&gt;, I decided that I wanted to eliminate all such methods from a project.&lt;/p&gt;
&lt;p&gt;Here is the regex I wrote to isolate the pattern:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ag &amp;#39;def (\w+);?\s+@\1;?\s+end&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The semicolon catches one-line getter methods as well as the more common three-line.&lt;/p&gt;</description></item><item><title>MD5 File Signatures</title><link>https://jakeworth.com/tils/md5-file-signatures/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/md5-file-signatures/</guid><description>&lt;p&gt;The command &lt;code&gt;md5 &amp;lt;file&amp;gt;&lt;/code&gt; generates a unique 32-digit hexadecimal number. This can serve as a signature for a file in its particular state, letting you know when it has changed.&lt;/p&gt;
&lt;p&gt;Example usage:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ touch test.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ md5 test.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MD5 &lt;span style="color:#f92672"&gt;(&lt;/span&gt;test.txt&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; d41d8cd98f00b204e9800998ecf8427e
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ echo &lt;span style="color:#e6db74"&gt;&amp;#39;some content&amp;#39;&lt;/span&gt; &amp;gt; test.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ md5 test.txt
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; MD5 &lt;span style="color:#f92672"&gt;(&lt;/span&gt;test.txt&lt;span style="color:#f92672"&gt;)&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&lt;/span&gt; eb9c2bf0eb63f3a7bc0ea37ef18aeba5
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Printing with lpr</title><link>https://jakeworth.com/tils/printing-with-lpr/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/printing-with-lpr/</guid><description>&lt;p&gt;Recently while trying to fix a printer I used &lt;code&gt;lpr&lt;/code&gt; a bunch of times. It&amp;rsquo;s not exactly new to me, but never fails to surprise people when I use it.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;lpr&lt;/code&gt; submits files for printing to your default printer in OSX.&lt;/p&gt;
&lt;p&gt;Print a file:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;lpr README.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Print the current file in your Vim session, with a &lt;em&gt;cool job name&lt;/em&gt;:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:! lpr -T &amp;#39;cool job name&amp;#39; %
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Print two copies to a specific printer:&lt;/p&gt;</description></item><item><title>Reverse a String</title><link>https://jakeworth.com/tils/reverse-a-string/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/reverse-a-string/</guid><description>&lt;p&gt;Reverse a string with the &lt;code&gt;rev&lt;/code&gt; command.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ echo &lt;span style="color:#e6db74"&gt;&amp;#39;test&amp;#39;&lt;/span&gt; | rev
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;tset
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It also works with files.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ rev Procfile
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;br.amup/gifnoc C- amup cexe eldnub :bew
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Run Previous Command</title><link>https://jakeworth.com/tils/run-previous-command/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/run-previous-command/</guid><description>&lt;p&gt;Previously run commands can be viewed with the &lt;code&gt;history&lt;/code&gt; command.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ history
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;10048&lt;/span&gt; git checkout master
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;10049&lt;/span&gt; gpr
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;10050&lt;/span&gt; rake
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;With this list, you can rerun any command using &lt;code&gt;!n&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ !10048
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Already on &lt;span style="color:#e6db74"&gt;&amp;#39;master&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The command &lt;code&gt;!!&lt;/code&gt; prints the last command you ran, then runs it. Here is an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LICENSE.md README.md bash cucumber rails
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;$ !!
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;ls
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;LICENSE.md README.md bash cucumber rails
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Replace the second &lt;code&gt;!&lt;/code&gt; with the first few letters of a command you have previously run, and bash will search for, print, and run the most recent instance.&lt;/p&gt;</description></item><item><title>Screen Flashing in OSX</title><link>https://jakeworth.com/tils/screen-flashing-in-osx/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/screen-flashing-in-osx/</guid><description>&lt;p&gt;I like a quiet computer. But I also like tab-completing commands in the terminal, which produces a necessary alert from time to time.&lt;/p&gt;
&lt;p&gt;A solution I found today is to use OSX Accessibility features to add a screen flash on alerts, then disable the sounds.&lt;/p&gt;
&lt;p&gt;System Preferences &amp;gt; Accessibility &amp;gt; Hearing menu, choose &amp;lsquo;Audio&amp;rsquo; &amp;gt; Check &amp;lsquo;Flash the screen when an alert occurs&amp;rsquo;&lt;/p&gt;</description></item><item><title>Send Processes to the Background</title><link>https://jakeworth.com/tils/send-processes-to-the-background/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/send-processes-to-the-background/</guid><description>&lt;p&gt;Processes on any POSIX-compliant computer can be sent to the background with &lt;code&gt;CTRL-Z&lt;/code&gt; (&lt;code&gt;&amp;lt;prefix&amp;gt; + Z&lt;/code&gt; for the tmux-ers) and returned to the foreground with &lt;code&gt;fg&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;Here is an example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;user@computer:~% ping www.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;PING www.google.com &lt;span style="color:#f92672"&gt;(&lt;/span&gt;74.125.228.212&lt;span style="color:#f92672"&gt;)&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;56&lt;/span&gt; data bytes
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; bytes from 74.125.228.212: icmp_seq&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;52&lt;/span&gt; time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;41.574 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; bytes from 74.125.228.212: icmp_seq&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt; ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;52&lt;/span&gt; time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;42.836 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; bytes from 74.125.228.212: icmp_seq&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt; ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;52&lt;/span&gt; time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;53.527 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;^Z
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;zsh: suspended ping www.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;user@computer:~% fg
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;1&lt;span style="color:#f92672"&gt;]&lt;/span&gt; + continued ping www.google.com
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; bytes from 74.125.228.212: icmp_seq&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;52&lt;/span&gt; time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;42.433 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; bytes from 74.125.228.212: icmp_seq&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;4&lt;/span&gt; ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;52&lt;/span&gt; time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;42.401 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; bytes from 74.125.228.212: icmp_seq&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt; ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;52&lt;/span&gt; time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;42.837 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;64&lt;/span&gt; bytes from 74.125.228.212: icmp_seq&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;6&lt;/span&gt; ttl&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;52&lt;/span&gt; time&lt;span style="color:#f92672"&gt;=&lt;/span&gt;44.203 ms
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;^C
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;--- www.google.com ping statistics ---
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;7&lt;/span&gt; packets transmitted, &lt;span style="color:#ae81ff"&gt;7&lt;/span&gt; packets received, 0.0% packet loss
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Start Postgres.app from the Command Line</title><link>https://jakeworth.com/tils/start-postgresapp-from-the-command-line/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/start-postgresapp-from-the-command-line/</guid><description>&lt;p&gt;Today I was trying to restore a production Postgres dump on a remote machine, to test some migrations. I haven&amp;rsquo;t granted myself Heroku production database access, hence the SSH into a machine with a Heroku user that has access.&lt;/p&gt;
&lt;p&gt;I quickly hit a problem— this remote machine runs Postgres using &lt;a href="http://postgresapp.com/"&gt;Postgres.app&lt;/a&gt;. Without that program, I&amp;rsquo;m out of luck. No local Postgres server, no production database restore, no testing.&lt;/p&gt;
&lt;p&gt;It turns out you can start Postgres.app from the command line. Find the executable and call it.&lt;/p&gt;</description></item><item><title>Watch That Program</title><link>https://jakeworth.com/tils/watch-that-program/</link><pubDate>Wed, 21 Apr 2021 16:50:27 -0400</pubDate><guid>https://jakeworth.com/tils/watch-that-program/</guid><description>&lt;p&gt;Have you ever been working in the terminal and found yourself repeating the same command many times? Delegate that work to the computer.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;watch&lt;/code&gt; comes with Linux and can be installed on OSX via homebrew. It executes a program periodically, defaulting to every two seconds.&lt;/p&gt;
&lt;p&gt;We used it today while writing a database backup script. Instead of checking our dump directory every time a cron job executed, we ran &lt;code&gt;watch ls&lt;/code&gt;, and watched the script succeed or fail with live updates.&lt;/p&gt;</description></item><item><title>ExtractRSpecLet</title><link>https://jakeworth.com/tils/extractrspeclet/</link><pubDate>Wed, 21 Apr 2021 11:13:08 -0400</pubDate><guid>https://jakeworth.com/tils/extractrspeclet/</guid><description>&lt;p&gt;Today I got to see the &lt;code&gt;:ExtractRspecLet&lt;/code&gt; command from the &lt;a href="https://github.com/jgdavey/vim-weefactor"&gt;vim-weefactor&lt;/a&gt; plugin. It does what the names suggests, converting this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# spec/model/foobar_spec.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;foo &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;FactoryGirl&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;create &lt;span style="color:#e6db74"&gt;:foobar&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;To this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# spec/model/foobar_spec.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;let(&lt;span style="color:#e6db74"&gt;:foo&lt;/span&gt;) { &lt;span style="color:#66d9ef"&gt;FactoryGirl&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;create &lt;span style="color:#e6db74"&gt;:foobar&lt;/span&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;It also moved the new &lt;code&gt;let&lt;/code&gt; from inside my &lt;code&gt;it&lt;/code&gt; block to right underneath my &lt;code&gt;context&lt;/code&gt; block. Awesome!&lt;/p&gt;
&lt;p&gt;h/t Josh Davey and Dillon Hafer&lt;/p&gt;</description></item><item><title>Upgrade Rubygems</title><link>https://jakeworth.com/tils/upgrade-rubygems/</link><pubDate>Wed, 21 Apr 2021 09:28:21 -0400</pubDate><guid>https://jakeworth.com/tils/upgrade-rubygems/</guid><description>&lt;p&gt;To update rubygems:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;gem install rubygems-update
update_rubygems
gem update --system
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Reset a Gem</title><link>https://jakeworth.com/tils/reset-a-gem/</link><pubDate>Tue, 20 Apr 2021 17:12:51 -0400</pubDate><guid>https://jakeworth.com/tils/reset-a-gem/</guid><description>&lt;p&gt;If you&amp;rsquo;ve been mucking around in your Ruby dependencies, &lt;code&gt;bundle pristine&lt;/code&gt; is
your friend; it resets all of the gems in your Gemfile to their pristine
condition.&lt;/p&gt;
&lt;p&gt;This can be a slow on a big project. Target the specific gems you worked on today with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ bundle pristine &amp;lt;gemname&amp;gt;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Semicolon Breaks Everything</title><link>https://jakeworth.com/tils/semicolon-breaks-everything/</link><pubDate>Fri, 14 Jun 2019 11:58:15 -0400</pubDate><guid>https://jakeworth.com/tils/semicolon-breaks-everything/</guid><description>&lt;p&gt;&amp;ldquo;Select isn&amp;rsquo;t broken.&amp;rdquo; If you&amp;rsquo;re working on a CSS file, and none of your
changes are being applied, check for typos, crashed servers, misplaced files,
etc. Once you&amp;rsquo;ve ruled out simple mistakes, you might have a syntax error like
this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;klass&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;opacity&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}&lt;span style="color:#f92672"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;The trailing semicolon is incorrect, and none of the CSS below it can be
understood by the browser.&lt;/p&gt;
&lt;p&gt;Change this to:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-css" data-lang="css"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;.&lt;span style="color:#a6e22e"&gt;klass&lt;/span&gt; {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;opacity&lt;/span&gt;: &lt;span style="color:#ae81ff"&gt;0.5&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;There may be some environments where a broken CSS file fails loudly; Code
Sandbox or Codepens are not among them. If you&amp;rsquo;re changing CSS and nothing is
happening, start looking for syntax errors.&lt;/p&gt;</description></item><item><title>Ignore Ripgrep Ignore</title><link>https://jakeworth.com/tils/ignore-ripgrep-ignore/</link><pubDate>Sat, 10 Nov 2018 11:04:17 -0500</pubDate><guid>https://jakeworth.com/tils/ignore-ripgrep-ignore/</guid><description>&lt;p&gt;I have an &lt;code&gt;.rgignore&lt;/code&gt; file that ignores half of a monorepo that I almost never
want to search in. Sometimes though, I do need to search that repo, and I&amp;rsquo;d rather not
edit my ignore file.&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s how I override it for one search:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;rg &amp;#34;I mean,&amp;#34; --no-ignore
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This will search in every directory, even those I&amp;rsquo;m ignoring via the
&lt;code&gt;.rgignore&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Pipe to pbcopy</title><link>https://jakeworth.com/tils/standard-output-to-clipboard-buffer/</link><pubDate>Sun, 26 Aug 2018 17:56:33 -0400</pubDate><guid>https://jakeworth.com/tils/standard-output-to-clipboard-buffer/</guid><description>&lt;p&gt;Adding &lt;code&gt;| pbcopy&lt;/code&gt; to the end of any command will send the standard output to your clipboard.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ls -al | pbcopy&lt;/code&gt; inside a rails project directory allowed me to paste this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;Gemfile
Gemfile.lock
README.md
Rakefile
app
bin
config
config.ru
db
features
lib
log
public
script
spec
test
tmp
vendor
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Open Every Site in a Chrome Bookmarks Folder</title><link>https://jakeworth.com/tils/open-every-site-in-a-chrome-bookmarks-folder-with-one-click/</link><pubDate>Sat, 17 Dec 2016 09:53:09 -0500</pubDate><guid>https://jakeworth.com/tils/open-every-site-in-a-chrome-bookmarks-folder-with-one-click/</guid><description>&lt;p&gt;When you command-click on a Chrome bookmarks folder, it opens every link in the
folder in a new tab.&lt;/p&gt;
&lt;p&gt;I did this by accident; so what&amp;rsquo;s the use case? I use bookmark folders to
categorize my &amp;lsquo;work links&amp;rsquo;: hosting, error monitoring, Git hosting, online
docs, etc. With this TIL, I could use this folder to open a new Chrome session
and instantly load it with all the pages I need to be effective.&lt;/p&gt;</description></item><item><title>Vim Regex Word Boundaries</title><link>https://jakeworth.com/tils/vim-regex-word-boundaries/</link><pubDate>Tue, 20 Sep 2016 07:46:37 -0500</pubDate><guid>https://jakeworth.com/tils/vim-regex-word-boundaries/</guid><description>&lt;p&gt;Today while writing a Vim regex to change every instance of &lt;code&gt;it&lt;/code&gt; (ignoring larger matches like &lt;code&gt;itemized&lt;/code&gt;), we stumbled upon Vim regex word boundary matching.&lt;/p&gt;
&lt;p&gt;Given this file:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;foo
foobar
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The following Vim regex will match on both the first and second line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:%&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/foo/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baz&lt;/span&gt;/&lt;span style="color:#a6e22e"&gt;g&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;But with word boundaries, we&amp;rsquo;ll only match (and change) the first line, because only the first &lt;code&gt;foo&lt;/code&gt; is a standalone word:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:%&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/\&amp;lt;foo\&amp;gt;/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;baz&lt;/span&gt;/&lt;span style="color:#a6e22e"&gt;g&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Delete Remote Git Tags</title><link>https://jakeworth.com/tils/delete-remote-git-tags/</link><pubDate>Fri, 18 Mar 2016 14:18:40 -0500</pubDate><guid>https://jakeworth.com/tils/delete-remote-git-tags/</guid><description>&lt;p&gt;Tagging releases with Git is a good idea. In case your tags get off track, here is how you delete a Git tag locally and on a remote:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ git tag -d abc
$ git push origin :refs/tags/abc
To git@github.com:hashrocket/hr-til
- [deleted] abc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;It gets trickier if you&amp;rsquo;re using Semantic Versioning, which includes dots in the tag name. The above won&amp;rsquo;t work for &lt;code&gt;v16.0.0&lt;/code&gt;. This will:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ git tag -d v16.0.0
$ git push origin :v16.0.0
To git@github.com:hashrocket/hr-til
- [deleted] v16.0.0
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Git Log With Authors</title><link>https://jakeworth.com/tils/git-log-with-authors/</link><pubDate>Thu, 25 Feb 2016 13:29:59 -0600</pubDate><guid>https://jakeworth.com/tils/git-log-with-authors/</guid><description>&lt;p&gt;In my &lt;a href="https://til.hashrocket.com/posts/32d01c979e-git-log-since"&gt;never-ending quest&lt;/a&gt; to better summarize my work at the end of the day using computers, I discovered today the Git &lt;code&gt;--author&lt;/code&gt; flag. It works like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ glg --since=midnight --author=dev+jwworth+mikechau@hashrocket.com
* 4ba91a8 (HEAD, origin/checkout, checkout) Add guard for manual entry of employee discount
* 3a4e4c9 Seed a coupon and code and auto-apply in preview
* cb1adee Add discount
...
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The alias &lt;code&gt;glg&lt;/code&gt; is discussed &lt;a href="https://til.hashrocket.com/posts/32d01c979e-git-log-since"&gt;here&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;I use this when multiple developers or teams are committing throughout the day to the same repository, to disambiguate our work from others. Ready to paste into your billing software of choice.&lt;/p&gt;</description></item><item><title>Count Links in a Markdown File</title><link>https://jakeworth.com/tils/count-links-in-a-markdown-file/</link><pubDate>Sun, 14 Feb 2016 17:43:36 -0600</pubDate><guid>https://jakeworth.com/tils/count-links-in-a-markdown-file/</guid><description>&lt;p&gt;Today I learned a great way to count the links in a README or link collection. Vim Regex!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:%&lt;span style="color:#a6e22e"&gt;s&lt;/span&gt;&lt;span style="color:#e6db74"&gt;/- \[/&lt;/span&gt;/&lt;span style="color:#a6e22e"&gt;n&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;In Vimspeak:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;On every line, find all of the times where &lt;code&gt;- [&lt;/code&gt; (the beginning of a Markdown
bulleted hyperlink) occurs, count them, and report the number of matches.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;See &lt;code&gt;:help substitute&lt;/code&gt; in Vim for more information.&lt;/p&gt;
&lt;p&gt;h/t Josh Branchaud&lt;/p&gt;</description></item><item><title>Query the Size of Postgres Array</title><link>https://jakeworth.com/tils/query-the-size-of-postgres-array/</link><pubDate>Sun, 14 Feb 2016 16:57:20 -0600</pubDate><guid>https://jakeworth.com/tils/query-the-size-of-postgres-array/</guid><description>&lt;p&gt;Today I learned how to query the size of a Postgres array. There are (at least) two methods that work.&lt;/p&gt;
&lt;p&gt;The first is &lt;code&gt;array_length&lt;/code&gt;. This requires you to know the array dimension you seek; a useful filter, although most of the time this will probably be &lt;code&gt;1&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hr&lt;span style="color:#f92672"&gt;-&lt;/span&gt;til_development&lt;span style="color:#f92672"&gt;=#&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;select&lt;/span&gt; title &lt;span style="color:#66d9ef"&gt;from&lt;/span&gt; posts
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;hr&lt;span style="color:#f92672"&gt;-&lt;/span&gt;til_development&lt;span style="color:#f92672"&gt;=#&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;where&lt;/span&gt; array_length(slack_notified_at_likes_threshold, &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;) &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; title
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;-------------------------------------------
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Because Javascript
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; Percent Notation
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; DIY Grids &lt;span style="color:#66d9ef"&gt;for&lt;/span&gt; Designing UI &lt;span style="color:#66d9ef"&gt;in&lt;/span&gt; Illustrator
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;(&lt;span style="color:#ae81ff"&gt;3&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;rows&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When the dimension is &lt;code&gt;1&lt;/code&gt;, a more terse solution is &lt;code&gt;cardinality&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>PostgreSQL Empty Array as Default Value</title><link>https://jakeworth.com/tils/default-to-empty-array-in-postgres/</link><pubDate>Sun, 14 Feb 2016 15:46:54 -0600</pubDate><guid>https://jakeworth.com/tils/default-to-empty-array-in-postgres/</guid><description>&lt;p&gt;We can add a PostgreSQL array column with a default empty array using:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-sql" data-lang="sql"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;add&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;column&lt;/span&gt; things integer[] &lt;span style="color:#66d9ef"&gt;not&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;null&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;default&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;{}&amp;#39;&lt;/span&gt;;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Variable Hoisting in Ruby</title><link>https://jakeworth.com/tils/variable-hoisting-in-ruby/</link><pubDate>Wed, 10 Feb 2016 20:45:51 -0600</pubDate><guid>https://jakeworth.com/tils/variable-hoisting-in-ruby/</guid><description>&lt;p&gt;This afternoon my pair and I spent quite a while on a subtle bug. The culprit? Variable hoisting.&lt;/p&gt;
&lt;p&gt;Take this file:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Test&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;self&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;hoist&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; require &lt;span style="color:#e6db74"&gt;&amp;#39;pry&amp;#39;&lt;/span&gt;; binding&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pry;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; bar &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Test&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;hoist
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When we hit the PRY debugger, what will the value of &lt;code&gt;bar&lt;/code&gt; be? I would have thought it would raise &lt;code&gt;NameError&lt;/code&gt;, because &lt;code&gt;bar&lt;/code&gt; has seemingly not yet been defined.&lt;/p&gt;
&lt;p&gt;Wrong:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ ruby test.rb
From: /test.rb @ line 4 Test.hoist:
2: def self.hoist
3: require &amp;#39;pry&amp;#39;; binding.pry;
=&amp;gt; 4: bar = 1
5: end
[1] pry(Test)&amp;gt; bar
=&amp;gt; nil
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;When Ruby parses a file, it &amp;lsquo;hoists&amp;rsquo; each variable to the top of its scope, declaring and setting it to &lt;code&gt;nil&lt;/code&gt;, even if that variable is never assigned by our code. So variables inside an &lt;code&gt;if false&lt;/code&gt; conditional get hoisted and set to &lt;code&gt;nil&lt;/code&gt;, as described in this &lt;a href="http://eftimov.net/variable-hoisting-ruby"&gt;blog post&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Get help with Pathogen</title><link>https://jakeworth.com/tils/get-help-with-pathogen/</link><pubDate>Wed, 13 Jan 2016 19:56:33 -0600</pubDate><guid>https://jakeworth.com/tils/get-help-with-pathogen/</guid><description>&lt;p&gt;Today I found a great command in Pathogen.vim, &lt;code&gt;:Helptags&lt;/code&gt;. This is a riff off &lt;code&gt;:helptags {dir}&lt;/code&gt;, a Vim feature that builds helptags for directory &lt;code&gt;{dir}&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;:Helptags&lt;/code&gt; does the same for all the directories in your &lt;code&gt;runtimepath&lt;/code&gt;, which defaults on Unix and Mac OS X to:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;#34;$HOME/.vim,
$VIM/vimfiles,
$VIMRUNTIME,
$VIM/vimfiles/after,
$HOME/.vim/after&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The use case here is when you&amp;rsquo;ve just loaded a new plugin into your Vim bundle, you open up Vim, and &lt;code&gt;:h {my_new_plugin}&lt;/code&gt; isn&amp;rsquo;t &amp;lsquo;helping&amp;rsquo; you out.&lt;/p&gt;</description></item><item><title>Generate a Rails Secret Key</title><link>https://jakeworth.com/tils/generate-a-rails-secret-key/</link><pubDate>Tue, 12 Jan 2016 13:55:55 -0600</pubDate><guid>https://jakeworth.com/tils/generate-a-rails-secret-key/</guid><description>&lt;p&gt;Have you ever wondered about those secret keys found in &lt;code&gt;config/secrets.yml&lt;/code&gt; of your Rails app? The comments generated in that file describe the keys as &amp;lsquo;used for verifying the integrity of signed cookies.&amp;rsquo;&lt;/p&gt;
&lt;p&gt;Great&amp;hellip; but what if they become compromised? Or we need to change them? We can generate new ones.&lt;/p&gt;
&lt;p&gt;Rails provides &lt;code&gt;rake secret&lt;/code&gt; for just this purpose.&lt;/p&gt;
&lt;p&gt;The source code is &lt;a href="https://github.com/rails/rails/blob/7f18ea14c893cb5c9f04d4fda9661126758332b5/railties/lib/rails/tasks/misc.rake#L2"&gt;here&lt;/a&gt;. It&amp;rsquo;s pretty simple; the code simply requires &lt;code&gt;SecureRandom&lt;/code&gt; and spits out a string. If you want to be really clever, you can pipe the string directly into your Vim buffer for the config file, with &lt;code&gt;:.! rake secret&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Show Model and Grep with Pry-rails</title><link>https://jakeworth.com/tils/show-model-and-grep-with-pryrails/</link><pubDate>Fri, 08 Jan 2016 13:11:52 -0600</pubDate><guid>https://jakeworth.com/tils/show-model-and-grep-with-pryrails/</guid><description>&lt;p&gt;This week Josh Branchaud wrote about &lt;code&gt;show-models&lt;/code&gt; in Pry-rails:&lt;/p&gt;
&lt;p&gt;&lt;a href="http://til.hashrocket.com/posts/62f61ee06f-show-rails-models-with-pry"&gt;http://til.hashrocket.com/posts/62f61ee06f-show-rails-models-with-pry&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;This method has two nice variants. &lt;code&gt;show-model User&lt;/code&gt; shows you that model, useful in a large database.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;show-models&lt;/code&gt; also accepts &lt;code&gt;--grep&lt;/code&gt; for searching:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt; pry(main)&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; show&lt;span style="color:#f92672"&gt;-&lt;/span&gt;models &lt;span style="color:#f92672"&gt;--&lt;/span&gt;grep published
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Post&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; id: integer
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;title&lt;/span&gt;: string
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;published_at&lt;/span&gt;: datetime &lt;span style="color:#75715e"&gt;# &amp;#39;published&amp;#39; is highlighted&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Set a Default Scope</title><link>https://jakeworth.com/tils/set-a-default-scope/</link><pubDate>Fri, 08 Jan 2016 10:23:35 -0600</pubDate><guid>https://jakeworth.com/tils/set-a-default-scope/</guid><description>&lt;p&gt;ActiveRecord provides &lt;code&gt;default_scope&lt;/code&gt;, which you can use to control how records are returned. An example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# app/model/chapter.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;Chapter&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ActiveRecord&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Base&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; default_scope { order(&lt;span style="color:#e6db74"&gt;:title&lt;/span&gt;) }
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, instead of this (ordered by ID):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Chapter&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;all&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pluck(&lt;span style="color:#e6db74"&gt;:title&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;take(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;BALINESE CAUSE&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;BUILDING RAT&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;TAIL&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;LILAC MERCURY&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;PUMP SQUARE&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We get this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;Chapter&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;all&lt;span style="color:#f92672"&gt;.&lt;/span&gt;pluck(&lt;span style="color:#e6db74"&gt;:title&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;take(&lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;AFGHANISTAN COAT&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ALCOHOL GONG&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ANTARCTICA BULL&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;ASPARAGUS&amp;#34;&lt;/span&gt;,
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;BALINESE CAUSE&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Beware, this decision can lead to inexplicable behavior down the road. Use with caution.&lt;/p&gt;
&lt;p&gt;One use case I&amp;rsquo;ve heard is soft deletes. We might not want soft-deleted records appearing in &lt;code&gt;.all&lt;/code&gt;:&lt;/p&gt;</description></item><item><title>Change Inner Tag Block</title><link>https://jakeworth.com/tils/change-inner-tag-block/</link><pubDate>Thu, 07 Jan 2016 18:40:11 -0600</pubDate><guid>https://jakeworth.com/tils/change-inner-tag-block/</guid><description>&lt;p&gt;Vim has excellent commands for changing the contents of parentheses (&lt;code&gt;ci(&lt;/code&gt;), brackets (&lt;code&gt;ci[&lt;/code&gt;), and squiggly braces (&lt;code&gt;ci{&lt;/code&gt;) (as well as single quotes, double quotes, backticks, etc.). But what about tags?&lt;/p&gt;
&lt;p&gt;Place your cursor anywhere inside the tags, type &lt;code&gt;cit&lt;/code&gt; in Visual mode, and this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-haml" data-lang="haml"&gt;&amp;lt;div&amp;gt;Begone&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Becomes:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-haml" data-lang="haml"&gt;&amp;lt;div&amp;gt;&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;d&lt;/code&gt; works too, but I prefer &lt;code&gt;c&lt;/code&gt; because it puts you in Insert mode at the end of the opening tag, ready to type.&lt;/p&gt;</description></item><item><title>Succeed, Precede, and Surround in Haml</title><link>https://jakeworth.com/tils/succeed-precede-and-surround-in-haml/</link><pubDate>Wed, 06 Jan 2016 21:59:41 -0600</pubDate><guid>https://jakeworth.com/tils/succeed-precede-and-surround-in-haml/</guid><description>&lt;p&gt;Haml&amp;rsquo;s design makes HTML and Ruby tricky to mix inline. But we have Haml helper methods to make it easier.&lt;/p&gt;
&lt;p&gt;Here is &lt;code&gt;succeed&lt;/code&gt; in action:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code class="language-haml" data-lang="haml"&gt;Developer at
= succeed &amp;#39;, &amp;#39; do
= link_to &amp;#34;Hashrocket&amp;#34;, &amp;#34;https://hashrocket.com/&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;This becomes:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-html" data-lang="html"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;Developer at
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&amp;lt;&lt;span style="color:#f92672"&gt;a&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;href&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;https://hashrocket.com/&amp;#34;&lt;/span&gt;&amp;gt;Hashrocket&amp;lt;/&lt;span style="color:#f92672"&gt;a&lt;/span&gt;&amp;gt;,
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Notice the comma at the end, outside of the &lt;code&gt;a&lt;/code&gt; tag?&lt;/p&gt;
&lt;p&gt;&lt;code&gt;precede&lt;/code&gt; and &lt;code&gt;surround&lt;/code&gt; work in a similar fashion, and do what we&amp;rsquo;d expect.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://haml.info/docs/yardoc/file.REFERENCE.html#succeed"&gt;http://haml.info/docs/yardoc/file.REFERENCE.html#succeed&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Increment and Decrement Numbers</title><link>https://jakeworth.com/tils/increment-and-decrement-numbers/</link><pubDate>Wed, 06 Jan 2016 17:28:17 -0600</pubDate><guid>https://jakeworth.com/tils/increment-and-decrement-numbers/</guid><description>&lt;p&gt;Vim has commands built-in to increment and decrement numbers: &lt;code&gt;CTRL-A&lt;/code&gt; and &lt;code&gt;CTRL-X&lt;/code&gt;, respectively.&lt;/p&gt;
&lt;p&gt;Combining this with a macro was a technique we tried today to build a large database migration. We ended up finding a more efficient solution, but it&amp;rsquo;s still a very magical key combination.&lt;/p&gt;
&lt;p&gt;Check out &lt;code&gt;:help CTRL-A&lt;/code&gt; for more info.&lt;/p&gt;
&lt;p&gt;h/t Josh Branchaud&lt;/p&gt;</description></item><item><title>Expect a Case-Insensitive Match</title><link>https://jakeworth.com/tils/expect-a-caseinsensitive-match/</link><pubDate>Tue, 05 Jan 2016 17:37:00 -0600</pubDate><guid>https://jakeworth.com/tils/expect-a-caseinsensitive-match/</guid><description>&lt;p&gt;We had a testing issue this week when a button&amp;rsquo;s text &lt;code&gt;save changes!&lt;/code&gt; was rendering as &lt;code&gt;SAVE CHANGES!&lt;/code&gt;, due to the CSS property &lt;code&gt;text-transform: uppercase&lt;/code&gt;. How do you test that?&lt;/p&gt;
&lt;p&gt;One technique is to use RSpec&amp;rsquo;s &lt;code&gt;match&lt;/code&gt; method, and include case insensitivity with &lt;code&gt;i&lt;/code&gt; (explored earlier &lt;a href="http://til.hashrocket.com/posts/4dc84ebcb8-caseinsensitive-substitution"&gt;here&lt;/a&gt;):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; button_text &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; expect(button_text)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to match(&lt;span style="color:#e6db74"&gt;&amp;#34;FOO&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;RSpec&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Expectations&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#e6db74"&gt;ExpectationNotMetError&lt;/span&gt;: expected &lt;span style="color:#e6db74"&gt;&amp;#34;foo&amp;#34;&lt;/span&gt; to match &lt;span style="color:#e6db74"&gt;&amp;#34;FOO&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# stuff&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; expect(button_text)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to match(&lt;span style="color:#e6db74"&gt;/FOO/i&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;We ultimately hard coded the expectation to &lt;code&gt;match(&amp;quot;FOO&amp;quot;)&lt;/code&gt;, because allowing &lt;code&gt;fOo&lt;/code&gt; and &lt;code&gt;FoO&lt;/code&gt; seemed too permissive. But it remains an option.&lt;/p&gt;</description></item><item><title>Testing Edit Forms</title><link>https://jakeworth.com/tils/testing-edit-forms/</link><pubDate>Tue, 17 Nov 2015 07:53:31 -0600</pubDate><guid>https://jakeworth.com/tils/testing-edit-forms/</guid><description>&lt;p&gt;Today I found a way to assert that an edit form&amp;rsquo;s inputs include a record&amp;rsquo;s saved data. I think it strikes a good balance between broad and narrow scope.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# spec/features/user_edits_kit_spec.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;within &lt;span style="color:#e6db74"&gt;&amp;#39;form&amp;#39;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; expect(page)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to have_selector(&lt;span style="color:#e6db74"&gt;&amp;#34;input[value=&amp;#39;Default copy.&amp;#39;]&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This asserts that some content is inside an input field in the form, rather than just anywhere on the page. You can narrow the scope as needed.&lt;/p&gt;</description></item><item><title>Delete a Line From Another Line</title><link>https://jakeworth.com/tils/delete-a-line-from-another-line/</link><pubDate>Mon, 09 Nov 2015 18:50:37 -0600</pubDate><guid>https://jakeworth.com/tils/delete-a-line-from-another-line/</guid><description>&lt;p&gt;Today I was cleaning up a test with an extra empty line at the top of the file, away from my Vim cursor. I wanted to delete it&amp;hellip; without moving the cursor.&lt;/p&gt;
&lt;p&gt;It seems like Vim almost lets you do this, with &lt;code&gt;:[range]d&lt;/code&gt;. But it leaves the cursor on the deleted line, which isn&amp;rsquo;t very magical.&lt;/p&gt;
&lt;p&gt;This is the hack we found:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:[range]d
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;#39;&amp;#39;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;''&lt;/code&gt; returns the cursor to the last jump point.&lt;/p&gt;</description></item><item><title>Ruby's Kernel::abort</title><link>https://jakeworth.com/tils/rubys-kernel-abort/</link><pubDate>Thu, 05 Nov 2015 18:30:56 -0600</pubDate><guid>https://jakeworth.com/tils/rubys-kernel-abort/</guid><description>&lt;p&gt;Today I used Ruby&amp;rsquo;s &lt;code&gt;Kernel::abort&lt;/code&gt; for the first time. It&amp;rsquo;s one of those incredibly useful methods I can&amp;rsquo;t believe I&amp;rsquo;ve never seen before.&lt;/p&gt;
&lt;p&gt;Observe:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# abort.rb {1}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;no_message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; abort
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;message&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; abort(&lt;span style="color:#e6db74"&gt;&amp;#39;Process terminated&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;pre tabindex="0"&gt;&lt;code&gt;$ irb
2.2.2 :001 &amp;gt; require &amp;#39;./abort&amp;#39;
=&amp;gt; true
2.2.2 :002 &amp;gt; no_message
$ irb {1}
2.2.2 :001 &amp;gt; require &amp;#39;./abort&amp;#39;
=&amp;gt; true
2.2.2 :002 &amp;gt; message
Process terminated
$
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Use it to bail from a script.&lt;/p&gt;</description></item><item><title>Cleanup PostgreSQL Databases</title><link>https://jakeworth.com/tils/cleanup-postgres-databases/</link><pubDate>Mon, 02 Nov 2015 16:36:56 -0600</pubDate><guid>https://jakeworth.com/tils/cleanup-postgres-databases/</guid><description>&lt;p&gt;Today I learned that I have thirty-nine Postgres databases on my computer, after running this command inside psql:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;\l ;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Each one is small, but I don&amp;rsquo;t like to carrying around old data. I ended up dropping nine of them, with:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;drop database foo_development;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;For a lighter storage and cognitive load.&lt;/p&gt;</description></item><item><title>Accessor Performance Gap</title><link>https://jakeworth.com/tils/accessor-performance-gap/</link><pubDate>Sun, 25 Oct 2015 12:34:28 -0500</pubDate><guid>https://jakeworth.com/tils/accessor-performance-gap/</guid><description>&lt;p&gt;This week I learned that &lt;code&gt;attr_reader&lt;/code&gt; is more performant than a simple getter method.&lt;/p&gt;
&lt;p&gt;Here’s a gist from five years ago where Aaron Patterson explains:&lt;/p&gt;
&lt;p&gt;&lt;a href="https://gist.github.com/pjb3/629716"&gt;https://gist.github.com/pjb3/629716&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;I ran that same benchmarking script today on Ruby 2.2.3. The gap has narrowed, but still exists:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ruby-2.2.3
Rehearsal -----------------------------------------------
method 0.070000 0.000000 0.070000 ( 0.074840)
attr_reader 0.050000 0.000000 0.050000 ( 0.052603)
-------------------------------------- total: 0.120000sec
user system total real
method 0.070000 0.000000 0.070000 ( 0.072229)
attr_reader 0.050000 0.000000 0.050000 ( 0.053374)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I like &lt;code&gt;attr_reader&lt;/code&gt; because it’s a Ruby convention and is one line instead of three. Now, I also like its performance relative to a getter.&lt;/p&gt;</description></item><item><title>The Alpha Commit</title><link>https://jakeworth.com/tils/the-alpha-commit/</link><pubDate>Wed, 21 Oct 2015 11:24:53 -0500</pubDate><guid>https://jakeworth.com/tils/the-alpha-commit/</guid><description>&lt;p&gt;I like to read commit logs.&lt;/p&gt;
&lt;p&gt;Today I wanted to see the first commit on a project. Here&amp;rsquo;s what I used:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git rev-list --max-parents=0 HEAD
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;em&gt;Show me the commits that led to&lt;/em&gt; &lt;code&gt;HEAD&lt;/code&gt; &lt;em&gt;in reverse chronological order; then limit that list to the commits with no parent.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Here&amp;rsquo;s a small modification, to show the entire commit rather than the SHA alone:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git show $(git rev-list --max-parents=0 HEAD)
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Rails restore_attributes</title><link>https://jakeworth.com/tils/rails-restoreattributes/</link><pubDate>Tue, 13 Oct 2015 11:56:12 -0500</pubDate><guid>https://jakeworth.com/tils/rails-restoreattributes/</guid><description>&lt;p&gt;Today I found a useful method in ActiveRecord, &lt;code&gt;restore_attributes&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This method restores attributes on a dirty model. Use it when you are hacking in the Rails console and want to quickly return to a clean slate.&lt;/p&gt;
&lt;p&gt;Dirty the record:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;[1] pry(main)&amp;gt; p = Post.first
Post Load (0.4ms) SELECT &amp;#34;posts&amp;#34;.* FROM &amp;#34;posts&amp;#34; ORDER BY &amp;#34;posts&amp;#34;.&amp;#34;id&amp;#34; ASC LIMIT 1
=&amp;gt; #&amp;lt;Post:0x007f8462b09eb8
id: 106,
title: &amp;#34;Hello World!&amp;#34;,
created_at: Sun, 09 Feb 2014 17:15:01 CST -06:00,
url_slug: &amp;#34;hello-world&amp;#34;&amp;gt;
[2] pry(main)&amp;gt; p.url_slug = &amp;#39;foobar&amp;#39;
=&amp;gt; &amp;#34;foobar&amp;#34;
[3] pry(main)&amp;gt; p.created_at = Time.now
=&amp;gt; 2015-10-13 11:41:37 -0500
[4] pry(main)&amp;gt; p
=&amp;gt; #&amp;lt;Post:0x007f8462b09eb8
id: 106,
title: &amp;#34;Hello World!&amp;#34;,
created_at: Tue, 13 Oct 2015 11:41:37 CDT -05:00,
url_slug: &amp;#34;foobar&amp;#34;&amp;gt;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;And restore:&lt;/p&gt;</description></item><item><title>Explore Buffers with BufExplorer</title><link>https://jakeworth.com/tils/explore-buffers-with-bufexplorer/</link><pubDate>Mon, 12 Oct 2015 17:38:15 -0500</pubDate><guid>https://jakeworth.com/tils/explore-buffers-with-bufexplorer/</guid><description>&lt;p&gt;I&amp;rsquo;m a huge fan of Vim buffers. I try to have my buffer list roughly mirror the files I am currently holding in my brain.&lt;/p&gt;
&lt;p&gt;The BufExplorer Vim plugin helps, and is included in the Hashrocket Dotmatrix. Today I learned to use the command &lt;code&gt;\bs&lt;/code&gt;, which opens a colorful buffer list that you can navigate with Vim directions.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/jlanzarotta/bufexplorer"&gt;https://github.com/jlanzarotta/bufexplorer&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Rails destroy</title><link>https://jakeworth.com/tils/rails-destroy/</link><pubDate>Tue, 06 Oct 2015 11:32:01 -0500</pubDate><guid>https://jakeworth.com/tils/rails-destroy/</guid><description>&lt;p&gt;The rails &lt;code&gt;generate&lt;/code&gt; (&lt;code&gt;g&lt;/code&gt;) command is useful for quickly creating the building blocks of a Rails app. Until you misspell or otherwise mess up a command:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;% rails g model blurg_post
invoke active_record
create db/migrate/20151006162244_create_blurg_posts.rb
create app/models/blurg_post.rb
invoke rspec
create spec/models/blurg_post_spec.rb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&amp;lsquo;Blurg post&amp;rsquo;? I meant &amp;lsquo;blog post&amp;rsquo;. Luckily, we can remove those auto-generated files as fast as we created them, with &lt;code&gt;destroy&lt;/code&gt; (&lt;code&gt;d&lt;/code&gt;).&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;% rails d model blurg_post
invoke active_record
remove db/migrate/20151006162244_create_blurg_posts.rb
remove app/models/blurg_post.rb
invoke rspec
remove spec/models/blurg_post_spec.rb
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;a href="http://edgeguides.rubyonrails.org/command_line.html#rails-destroy"&gt;http://edgeguides.rubyonrails.org/command_line.html#rails-destroy&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Git Log since</title><link>https://jakeworth.com/tils/git-log-since/</link><pubDate>Tue, 29 Sep 2015 17:42:09 -0500</pubDate><guid>https://jakeworth.com/tils/git-log-since/</guid><description>&lt;p&gt;At the end of each day, I try to record what I did, to jog my memory during the next morning&amp;rsquo;s standup. This is a helpful aid:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;git log --since=&amp;#34;24 hours ago&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;I SSH into my work machine and run this in my project&amp;rsquo;s root directory. Combined with an alias from the Hashrocket Dotmatrix, &lt;code&gt;glg&lt;/code&gt; (&lt;code&gt;git log --graph --oneline --decorate --color --all&lt;/code&gt;), I get a terse summary of the day&amp;rsquo;s work, ready to be pasted into your note-taking or project management tool of choice:&lt;/p&gt;</description></item><item><title>Fetch Your Environmental Variables</title><link>https://jakeworth.com/tils/fetch-your-environmental-variables/</link><pubDate>Sat, 26 Sep 2015 18:56:00 -0500</pubDate><guid>https://jakeworth.com/tils/fetch-your-environmental-variables/</guid><description>&lt;p&gt;It&amp;rsquo;s important to &lt;code&gt;fetch&lt;/code&gt; Ruby environmental variables rather than directly referencing them.&lt;/p&gt;
&lt;p&gt;This code depends on &amp;lsquo;secret_key&amp;rsquo;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ENV&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;secret_key&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When &amp;lsquo;secret_key&amp;rsquo; is not set, &amp;lsquo;key&amp;rsquo; will be assigned &lt;code&gt;nil&lt;/code&gt;, which is an object.&lt;/p&gt;
&lt;p&gt;Later, a call to &lt;code&gt;key.upcase&lt;/code&gt; will produce a &lt;code&gt;NoMethodError&lt;/code&gt;, because Ruby doesn&amp;rsquo;t know how to uppercase &lt;code&gt;nil&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;This is better:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;key &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ENV&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;fetch(&lt;span style="color:#e6db74"&gt;&amp;#39;secret_key&amp;#39;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Now, when &amp;lsquo;secret_key&amp;rsquo; is not set, &lt;code&gt;KeyError&lt;/code&gt; will be raised. The code fails fast.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;fetch&lt;/code&gt; takes a second argument as a default, which means you can even prevent &lt;code&gt;KeyError&lt;/code&gt; entirely, if you choose.&lt;/p&gt;</description></item><item><title>Seeding Golang's Rand</title><link>https://jakeworth.com/tils/seeding-golangs-rand/</link><pubDate>Fri, 25 Sep 2015 08:04:38 -0500</pubDate><guid>https://jakeworth.com/tils/seeding-golangs-rand/</guid><description>&lt;p&gt;&amp;lsquo;Random&amp;rsquo; numbers in Go don&amp;rsquo;t always seem random. This is because the &lt;code&gt;rand&lt;/code&gt; package defaults to a seed of 1.&lt;/p&gt;
&lt;p&gt;That&amp;rsquo;s great if you need a bunch of random numbers at the start of your program. Not great if you expect a different outcome each time you run the program.&lt;/p&gt;
&lt;p&gt;A solution is to seed &lt;code&gt;rand&lt;/code&gt; with Unix time. Try it in the &lt;code&gt;init()&lt;/code&gt; function:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;package&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;main&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;import&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;math/rand&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;time&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;func&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;init&lt;/span&gt;() {
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;rand&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Seed&lt;/span&gt;(&lt;span style="color:#a6e22e"&gt;time&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;Now&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;UTC&lt;/span&gt;().&lt;span style="color:#a6e22e"&gt;UnixNano&lt;/span&gt;())
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;}
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;...&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Build URLs with Window Location</title><link>https://jakeworth.com/tils/build-urls-with-window-location/</link><pubDate>Wed, 23 Sep 2015 21:45:56 -0500</pubDate><guid>https://jakeworth.com/tils/build-urls-with-window-location/</guid><description>&lt;p&gt;Want to build URLs with JavaScript? Try the&lt;code&gt;window.location&lt;/code&gt; object.&lt;/p&gt;
&lt;p&gt;This came from a React.js project we&amp;rsquo;re working on. It uses ES6 template string interpolation, which isn&amp;rsquo;t necessary but definitely is nice:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;`${window.location.protocol}//${window.location.host}/posts/${this.props.postID}/edit`
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Which becomes:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;&amp;#34;https://secret-project.com/posts/42/edit&amp;#34;
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Postgres Unlogged</title><link>https://jakeworth.com/tils/postgres-unlogged/</link><pubDate>Wed, 23 Sep 2015 07:37:27 -0500</pubDate><guid>https://jakeworth.com/tils/postgres-unlogged/</guid><description>&lt;p&gt;Using a Postgres table for caching? You might want to try making it &lt;code&gt;unlogged&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;unlogged&lt;/code&gt; tables are not written to the write-ahead log, which makes them much faster. This also means they are not crash-safe, and are truncated when a crash or unclean shutdown occurs. For caching purposes, that&amp;rsquo;s likely to be an acceptable tradeoff.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://www.postgresql.org/docs/current/static/sql-createtable.html"&gt;Documentation&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Go iota</title><link>https://jakeworth.com/tils/go-iota/</link><pubDate>Thu, 17 Sep 2015 13:24:16 -0500</pubDate><guid>https://jakeworth.com/tils/go-iota/</guid><description>&lt;p&gt;Go has an interesting feature called &lt;code&gt;iota&lt;/code&gt;. When declaring a list of constants, this keyword represents successive untyped integer constants.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; (
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;iota&lt;/span&gt; &lt;span style="color:#75715e"&gt;// foo == 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;bar&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;iota&lt;/span&gt; &lt;span style="color:#75715e"&gt;// bar == 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#a6e22e"&gt;baz&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;iota&lt;/span&gt; &lt;span style="color:#75715e"&gt;// baz == 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Anytime &lt;code&gt;const&lt;/code&gt; is invoked, the counter resets.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-go" data-lang="go"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;foo&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;iota&lt;/span&gt; &lt;span style="color:#75715e"&gt;// foo == 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;const&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;bar&lt;/span&gt; = &lt;span style="color:#66d9ef"&gt;iota&lt;/span&gt; &lt;span style="color:#75715e"&gt;// bar == 0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is a cool way to quickly define a list of integer constants, such as &amp;rsquo;true&amp;rsquo; and &amp;lsquo;false&amp;rsquo;, for later use.&lt;/p&gt;</description></item><item><title>Ruby Regex Literal</title><link>https://jakeworth.com/tils/ruby-regex-literal/</link><pubDate>Thu, 10 Sep 2015 22:35:52 -0500</pubDate><guid>https://jakeworth.com/tils/ruby-regex-literal/</guid><description>&lt;p&gt;Ruby has a nice percent string literal for regular expressions, &lt;code&gt;%r&lt;/code&gt;. It&amp;rsquo;s like &lt;code&gt;//&lt;/code&gt; but allows your regex to contain backslashes without escaping them.&lt;/p&gt;
&lt;p&gt;Check it out:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;2.1.0 :001 &amp;gt; &amp;#39;http://google.com&amp;#39;.gsub(/http:\/\/google.com/, &amp;#39;fine&amp;#39;)
=&amp;gt; &amp;#34;fine&amp;#34;
2.1.0 :002 &amp;gt; &amp;#39;http://google.com&amp;#39;.gsub(%r{http://google.com}, &amp;#39;better&amp;#39;)
=&amp;gt; &amp;#34;better&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;As the example implies, this is useful when matching URLs.&lt;/p&gt;
&lt;p&gt;&lt;a href="http://ruby-doc.org/core-2.2.3/doc/syntax/literals_rdoc.html#label-Percent+Strings"&gt;Documentation&lt;/a&gt;&lt;/p&gt;</description></item><item><title>Prepare / Execute</title><link>https://jakeworth.com/tils/prepare-execute/</link><pubDate>Tue, 08 Sep 2015 18:51:01 -0500</pubDate><guid>https://jakeworth.com/tils/prepare-execute/</guid><description>&lt;p&gt;You can store a PostgreSQL query with &lt;code&gt;prepare&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;db=# prepare posts_search as select title from posts limit 5;
PREPARE
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Call the method with &lt;code&gt;execute&lt;/code&gt;.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;db=# execute posts_search;
title
-----------------------------------
Hello World!
My First Pull Request: HAML
My First Pull Request: Sinatra
My First Pull Request: Capistrano
My First Pull Request: SASS
(5 rows)
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Deallocate the query with &lt;code&gt;deallocate&lt;/code&gt;, and you can set it again.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;db=# deallocate posts_search;
DEALLOCATE
db=# prepare posts_search as select title from posts limit 10;
PREPARE
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Psql Connect</title><link>https://jakeworth.com/tils/psql-connect/</link><pubDate>Tue, 08 Sep 2015 18:51:01 -0500</pubDate><guid>https://jakeworth.com/tils/psql-connect/</guid><description>&lt;p&gt;Want to change database connections from inside psql? You can!&lt;/p&gt;
&lt;p&gt;Psql, the REPL for Postgres, has a useful meta-command called &lt;code&gt;\connect&lt;/code&gt;, or &lt;code&gt;\c&lt;/code&gt;. This lets you establish a new connection to a Postgres server, while closing the current connection.&lt;/p&gt;
&lt;p&gt;Here is the required format:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;\c or \connect [ dbname [ username ] [ host ] [ port ] ] | conninfo
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Only &lt;code&gt;\c [my_database]&lt;/code&gt; is required; omitted parameters are taken from the previous connection.&lt;/p&gt;</description></item><item><title>Terminate Database Connections</title><link>https://jakeworth.com/tils/terminate_database_connections/</link><pubDate>Tue, 08 Sep 2015 18:51:01 -0500</pubDate><guid>https://jakeworth.com/tils/terminate_database_connections/</guid><description>&lt;p&gt;To maintain data integrity, certain actions like &lt;code&gt;rake db:drop&lt;/code&gt; will not execute when there are active sessions on a Postgres database. You&amp;rsquo;ll get an error like this:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;ERROR: database &amp;#34;database_name&amp;#34; is being accessed by other users
DETAIL: There are 2 other session(s) using the database.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Sessions can be killed from the command line, but a safer route is to kill them with a database method. First, revoke all public access from the database:&lt;/p&gt;</description></item><item><title>Keyword Precedence</title><link>https://jakeworth.com/tils/keyword-precedence/</link><pubDate>Thu, 02 Jul 2015 17:43:57 -0500</pubDate><guid>https://jakeworth.com/tils/keyword-precedence/</guid><description>&lt;p&gt;The Ruby keyword &lt;code&gt;not&lt;/code&gt; and the unary &lt;code&gt;!&lt;/code&gt; aren&amp;rsquo;t the same. They have a different precedence, and therefore are not interchangeable, despite seeming very similar.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;irb &amp;gt; not 3 == 4
=&amp;gt; true
irb &amp;gt; !3 == 4
=&amp;gt; false
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The first example is evaluated as &lt;code&gt;not (3 == 4)&lt;/code&gt;, or &lt;code&gt;not false&lt;/code&gt;, which is true. The second example is evaluated as &lt;code&gt;(not 3) == 4&lt;/code&gt;, or &lt;code&gt;false == 4&lt;/code&gt;, which is false.&lt;/p&gt;</description></item><item><title>Skid Keywords</title><link>https://jakeworth.com/tils/skid-keywords/</link><pubDate>Thu, 02 Jul 2015 15:28:02 -0500</pubDate><guid>https://jakeworth.com/tils/skid-keywords/</guid><description>&lt;p&gt;Ruby has a few interesting old keywords that use the underscore, or &amp;lsquo;skid&amp;rsquo;, to convey meta information about the file.&lt;/p&gt;
&lt;p&gt;Here they are in action:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# test.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;puts __ENCODING__
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;puts __FILE__
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;puts __LINE__
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;__END__
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;Because this is after &amp;#39;end&amp;#39;, it should not be executed
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Running this file produces:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ ruby test.rb
UTF-8
test.rb
3
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Pretty cool!&lt;/p&gt;</description></item><item><title>Change Column Null</title><link>https://jakeworth.com/tils/change-column-null/</link><pubDate>Sun, 28 Jun 2015 12:34:19 -0500</pubDate><guid>https://jakeworth.com/tils/change-column-null/</guid><description>&lt;p&gt;The &lt;code&gt;not null&lt;/code&gt; constraint is a great way to ensure data integrity. If a Rails model &lt;code&gt;validates_presence_of&lt;/code&gt; an attribute, that column should be &lt;code&gt;not null&lt;/code&gt; in the database.&lt;/p&gt;
&lt;p&gt;Rails has a special migration method for setting this constraint.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;change_column_null &lt;span style="color:#e6db74"&gt;:users&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;:mandatory_attribute&lt;/span&gt;, &lt;span style="color:#66d9ef"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;You could also use the &lt;code&gt;change_column&lt;/code&gt; method. The reason &lt;code&gt;change_column_null&lt;/code&gt; is a better choice is that &lt;code&gt;change_column&lt;/code&gt; requires you to state the type of the column; &lt;code&gt;change_column_null&lt;/code&gt; does not.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;change_column(table_name, column_name, type, options)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;change_column_null(table_name, column_name, null, default &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Classify and Constantize</title><link>https://jakeworth.com/tils/classify-and-constantize/</link><pubDate>Wed, 03 Jun 2015 22:28:22 -0500</pubDate><guid>https://jakeworth.com/tils/classify-and-constantize/</guid><description>&lt;p&gt;Metaprogramming! Today I created a variable &lt;code&gt;event&lt;/code&gt; that calls a serializer unique to the value of &lt;code&gt;event&lt;/code&gt;. Along the way I learned about the Rails methods &lt;code&gt;classify&lt;/code&gt; and &lt;code&gt;constantize&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;classify&lt;/code&gt; takes a plural table name and returns a class name.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;some_things&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;classify
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;SomeThing&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;constantize&lt;/code&gt; tries to find a constant with the name specified in the argument string.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Module&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;constantize
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;Module&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;Nothing&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;constantize
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#e6db74"&gt;NameError&lt;/span&gt;: uninitialized constant &lt;span style="color:#66d9ef"&gt;Nothing&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Here&amp;rsquo;s a sample of how I used these methods today (on the &amp;lsquo;Today I Learned&amp;rsquo; app itself):&lt;/p&gt;</description></item><item><title>Find Or Create By With Block</title><link>https://jakeworth.com/tils/find-or-create-by-with-block/</link><pubDate>Sat, 30 May 2015 16:50:30 -0500</pubDate><guid>https://jakeworth.com/tils/find-or-create-by-with-block/</guid><description>&lt;p&gt;The Rails &lt;code&gt;find_or_create_by&lt;/code&gt; method is great for bringing something into existence only once. I like to use it for database seeds, so you get the basic objects you need to make your development site useable, but don&amp;rsquo;t keep creating them over and over again.&lt;/p&gt;
&lt;p&gt;One feature I recently learned is that this method takes a block.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;User&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;find_or_create_by(&lt;span style="color:#e6db74"&gt;first_name&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;Jake&amp;#39;&lt;/span&gt;) &lt;span style="color:#66d9ef"&gt;do&lt;/span&gt; &lt;span style="color:#f92672"&gt;|&lt;/span&gt;user&lt;span style="color:#f92672"&gt;|&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; user&lt;span style="color:#f92672"&gt;.&lt;/span&gt;last_name &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Worth&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This lets you find the object, and if it doesn&amp;rsquo;t exist, create it with whatever attributes you need.&lt;/p&gt;</description></item><item><title>Edit the Current File Always</title><link>https://jakeworth.com/tils/edit-the-current-file-always/</link><pubDate>Fri, 29 May 2015 00:25:49 -0500</pubDate><guid>https://jakeworth.com/tils/edit-the-current-file-always/</guid><description>&lt;p&gt;The Vim command &lt;code&gt;:e&lt;/code&gt; edits a file. Add a bang, &lt;code&gt;:e!&lt;/code&gt;, to edit the current file &amp;lsquo;always&amp;rsquo;, discarding any changes to the current buffer.&lt;/p&gt;
&lt;p&gt;This is useful if you rename a file with a new file extension (i.e. &lt;code&gt;.txt&lt;/code&gt; to &lt;code&gt;.rb&lt;/code&gt;). &lt;code&gt;:e!&lt;/code&gt; reloads the file in Vim, picking up any customizations you have in your configuration files such as syntax highlighting.&lt;/p&gt;</description></item><item><title>Multipurpose Environmental Variables</title><link>https://jakeworth.com/tils/multipurpose-environmental-variables/</link><pubDate>Tue, 26 May 2015 21:25:36 -0500</pubDate><guid>https://jakeworth.com/tils/multipurpose-environmental-variables/</guid><description>&lt;p&gt;I use HTTP Basic auth in non-production environments because it ships with Rails and is easy to implement. The first time I used it, I set it up like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# app/controllers/application_controller.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ENV&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;http_basic_auth&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; http_basic_authenticate_with name: &lt;span style="color:#66d9ef"&gt;ENV&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;username&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;password&lt;/span&gt;: &lt;span style="color:#66d9ef"&gt;ENV&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;I used environmental variables so that no credentials were hard-coded, and so I could toggle it without deploying.&lt;/p&gt;
&lt;p&gt;Today I learned you can also implement it like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# app/controllers/application_controller.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; creds &lt;span style="color:#f92672"&gt;=&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ENV&lt;/span&gt;&lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;basic_auth_credentials&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; username, password &lt;span style="color:#f92672"&gt;=&lt;/span&gt; creds&lt;span style="color:#f92672"&gt;.&lt;/span&gt;split(&lt;span style="color:#e6db74"&gt;&amp;#39;:&amp;#39;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; http_basic_authenticate_with name: username, &lt;span style="color:#e6db74"&gt;password&lt;/span&gt;: password
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This requires an environmental variable called &lt;code&gt;basic_auth_credentials&lt;/code&gt;, set to &lt;code&gt;&amp;lt;username&amp;gt;:&amp;lt;password&amp;gt;&lt;/code&gt;. I prefer this because it allows one variable to serve two purposes: it toggles the feature and also contains the information the feature needs to work.&lt;/p&gt;</description></item><item><title>Puts Multiple Lines</title><link>https://jakeworth.com/tils/puts-multiple-lines/</link><pubDate>Tue, 26 May 2015 10:28:54 -0500</pubDate><guid>https://jakeworth.com/tils/puts-multiple-lines/</guid><description>&lt;p&gt;Ruby&amp;rsquo;s &lt;code&gt;puts&lt;/code&gt; can take multiple arguments!&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; :&lt;span style="color:#ae81ff"&gt;002&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; puts &lt;span style="color:#e6db74"&gt;&amp;#39;so&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;many&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;statements&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;to&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;puts&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;so
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;many
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;statements
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;to
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;puts
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Truthy Strings</title><link>https://jakeworth.com/tils/truthy-strings/</link><pubDate>Tue, 26 May 2015 10:28:48 -0500</pubDate><guid>https://jakeworth.com/tils/truthy-strings/</guid><description>&lt;p&gt;Ruby strings are truthy, and they evaluate to zero, unless they start with a number.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;nine to five&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to_i
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;9 to 5&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to_i
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;9&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Find and Replace Across Files</title><link>https://jakeworth.com/tils/find-and-replace-across-files/</link><pubDate>Thu, 21 May 2015 09:47:13 -0500</pubDate><guid>https://jakeworth.com/tils/find-and-replace-across-files/</guid><description>&lt;p&gt;Vim can find and replace strings across files, just like other text editors. It&amp;rsquo;s really (sort of) easy.&lt;/p&gt;
&lt;p&gt;First load all the files you want to change into the buffer with a splatted directory.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:args path/to/files/*/*
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Then, execute the substitution.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;:argdo %s/old_string/new_string/ge | update
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;The &lt;code&gt;e&lt;/code&gt; flag is important; it tells Vim not to issue an error if the search pattern fails. This will prevent &lt;code&gt;No Match&lt;/code&gt; errors from breaking the chain.&lt;/p&gt;</description></item><item><title>Minmax</title><link>https://jakeworth.com/tils/minmax/</link><pubDate>Mon, 18 May 2015 19:32:59 -0500</pubDate><guid>https://jakeworth.com/tils/minmax/</guid><description>&lt;p&gt;Ruby&amp;rsquo;s &lt;code&gt;Enumerable&lt;/code&gt; class includes &lt;code&gt;minmax&lt;/code&gt;, which returns a two element array with the minimum and maximum values of an enumerable.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;5&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#f92672"&gt;].&lt;/span&gt;minmax
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#39;alpha&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;bravo&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;zulu&amp;#39;&lt;/span&gt;&lt;span style="color:#f92672"&gt;].&lt;/span&gt;minmax
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;alpha&amp;#34;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#34;zulu&amp;#34;&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Call a Vimscript Method in Vim</title><link>https://jakeworth.com/tils/call-a-vimscript-method-in-vim/</link><pubDate>Sun, 17 May 2015 17:00:04 -0500</pubDate><guid>https://jakeworth.com/tils/call-a-vimscript-method-in-vim/</guid><description>&lt;p&gt;To call a Vimscript method in Vim, first source the file.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#a6e22e"&gt;source&lt;/span&gt; ~&lt;span style="color:#e6db74"&gt;/path/&lt;/span&gt;&lt;span style="color:#a6e22e"&gt;to&lt;/span&gt;/&lt;span style="color:#a6e22e"&gt;vimscript&lt;/span&gt;.&lt;span style="color:#a6e22e"&gt;vim&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Next, put the cursor over the method call, and run that line.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-vim" data-lang="vim"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;:&lt;span style="color:#a6e22e"&gt;exec&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;getline&lt;/span&gt;(&lt;span style="color:#e6db74"&gt;&amp;#34;.&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Case Insensitive Matchers</title><link>https://jakeworth.com/tils/case-insensitive-matchers/</link><pubDate>Fri, 15 May 2015 15:34:38 -0500</pubDate><guid>https://jakeworth.com/tils/case-insensitive-matchers/</guid><description>&lt;p&gt;You can make Ruby regex matchers case insensitive with an &lt;code&gt;i&lt;/code&gt;.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; :&lt;span style="color:#ae81ff"&gt;001&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Expected output&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=~&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/expected/&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;nil&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#ae81ff"&gt;2&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;1&lt;/span&gt;&lt;span style="color:#f92672"&gt;.&lt;/span&gt;&lt;span style="color:#ae81ff"&gt;0&lt;/span&gt; :&lt;span style="color:#ae81ff"&gt;002&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;Expected output&amp;#39;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=~&lt;/span&gt; &lt;span style="color:#e6db74"&gt;/expected/i&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#ae81ff"&gt;0&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This is useful when writing tests, when you care about a message, but are not interested in its exact format.&lt;/p&gt;</description></item><item><title>Current Value of a Setting</title><link>https://jakeworth.com/tils/current-value-of-a-setting/</link><pubDate>Thu, 14 May 2015 11:00:00 -0500</pubDate><guid>https://jakeworth.com/tils/current-value-of-a-setting/</guid><description>&lt;p&gt;Check the value of any Vim setting by adding a &lt;code&gt;?&lt;/code&gt; to the end of its name.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;# Validate spelling is turned off
:set spell?
=&amp;gt; nospell
# Validate incremental search is turned on
:set incsearch?
=&amp;gt; :incsearch
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Jump to the First Non-Blank Character</title><link>https://jakeworth.com/tils/jump-to-the-first-non-blank-character/</link><pubDate>Tue, 12 May 2015 18:45:11 -0500</pubDate><guid>https://jakeworth.com/tils/jump-to-the-first-non-blank-character/</guid><description>&lt;p&gt;With Vim you can jump down any &lt;em&gt;n&lt;/em&gt; amount of lines with &lt;code&gt;n + j&lt;/code&gt;, and back up with &lt;code&gt;n + k&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;An alternate command is &lt;code&gt;n + +&lt;/code&gt;, which jumps down to the first non-blank character, and &lt;code&gt;n + -&lt;/code&gt;, which jumps back up to the first non-blank character.&lt;/p&gt;</description></item><item><title>Redirect a Path</title><link>https://jakeworth.com/tils/redirect-a-path/</link><pubDate>Mon, 11 May 2015 17:17:51 -0500</pubDate><guid>https://jakeworth.com/tils/redirect-a-path/</guid><description>&lt;p&gt;To redirect a path in Rails:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# config/routes.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;get &lt;span style="color:#e6db74"&gt;&amp;#34;/authors&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; redirect(&lt;span style="color:#e6db74"&gt;&amp;#34;/designers&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This lets you take a difficult-to-type path name and expose it to your users as a simpler path name:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# config/routes.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;get &lt;span style="color:#e6db74"&gt;&amp;#34;/login&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; redirect(&lt;span style="color:#e6db74"&gt;&amp;#34;/auth/google_oauth2&amp;#34;&lt;/span&gt;)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Bypass Basic Auth</title><link>https://jakeworth.com/tils/bypass-basic-auth/</link><pubDate>Fri, 08 May 2015 13:23:33 -0400</pubDate><guid>https://jakeworth.com/tils/bypass-basic-auth/</guid><description>&lt;p&gt;Rails comes with HTTP Basic authentication built in. Adding this to a controller is how it&amp;rsquo;s done:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#75715e"&gt;# app/controllers/application_controller.rb&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;http_basic_authenticate_with name: &lt;span style="color:#e6db74"&gt;&amp;#39;name&amp;#39;&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;password&lt;/span&gt;: &lt;span style="color:#e6db74"&gt;&amp;#39;password&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When you visit a URL requiring authentication, you can bypass the authentication screen by adding your username and password to the beginning of the URL. For localhost, this would look like:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;name:password@localhost:3000
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Git Snapshot</title><link>https://jakeworth.com/tils/git-snapshot/</link><pubDate>Fri, 08 May 2015 12:33:10 -0400</pubDate><guid>https://jakeworth.com/tils/git-snapshot/</guid><description>&lt;p&gt;To save a snapshot of your current work in git, try this command:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-shell" data-lang="shell"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;git stash save &lt;span style="color:#e6db74"&gt;&amp;#34;snapshot: &lt;/span&gt;&lt;span style="color:#66d9ef"&gt;$(&lt;/span&gt;date&lt;span style="color:#66d9ef"&gt;)&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;amp;&amp;amp;&lt;/span&gt; git stash apply &lt;span style="color:#e6db74"&gt;&amp;#34;stash@{0}&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This saves your current work in a timestamped stash, without removing it. In Hashrocket&amp;rsquo;s dotmatrix this command is aliased to &lt;code&gt;git snapshot&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Close a File</title><link>https://jakeworth.com/tils/close-a-file/</link><pubDate>Fri, 08 May 2015 09:19:58 -0500</pubDate><guid>https://jakeworth.com/tils/close-a-file/</guid><description>&lt;p&gt;In Vim there are many ways to close a file. One of the best is &lt;code&gt;:x&lt;/code&gt;, also know as &lt;code&gt;:xit&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;:x&lt;/code&gt; writes and quits a file when changes have been made, like &lt;code&gt;:wq&lt;/code&gt;, but with one less keystroke.&lt;/p&gt;
&lt;p&gt;&lt;em&gt;An important distinction:&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;code&gt;:x&lt;/code&gt; and &lt;code&gt;:wq&lt;/code&gt; are similar, but not identical commands.&lt;/p&gt;
&lt;p&gt;The difference is that &lt;code&gt;:wq&lt;/code&gt; writes the current file and quits, as long as the file is not read-only and has a name, while &lt;code&gt;:x&lt;/code&gt; only writes if changes have been made. So, if you were to generate a file with Vim, make no changes, and try to write and quit with &lt;code&gt;:x&lt;/code&gt;, the file would not be written. Doing the same thing with &lt;code&gt;:wq&lt;/code&gt; would write the file.&lt;/p&gt;</description></item><item><title>Sort Alphabetically</title><link>https://jakeworth.com/tils/sort-alphabetically/</link><pubDate>Wed, 06 May 2015 20:05:31 -0500</pubDate><guid>https://jakeworth.com/tils/sort-alphabetically/</guid><description>&lt;p&gt;One way to make a list nicer to read is to sort it. Vim comes with a command built in for just this purpose.&lt;/p&gt;
&lt;p&gt;Here is a snippet from a Gemfile:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;gem &amp;#39;coffee-rails&amp;#39;, &amp;#39;~&amp;gt; 4.1.0&amp;#39;
gem &amp;#39;uglifier&amp;#39;, &amp;#39;&amp;gt;= 1.3.0&amp;#39;
gem &amp;#39;sass-rails&amp;#39;, &amp;#39;~&amp;gt; 5.0&amp;#39;
gem &amp;#39;puma&amp;#39;
gem &amp;#39;gravatar_image_tag&amp;#39;
gem &amp;#39;authem&amp;#39;
gem &amp;#39;jquery-rails&amp;#39;
gem &amp;#39;pg&amp;#39;
gem &amp;#39;redcarpet&amp;#39;
gem &amp;#39;rails_12factor&amp;#39;, group: :production
gem &amp;#39;sdoc&amp;#39;, &amp;#39;~&amp;gt; 0.4.0&amp;#39;, group: :doc
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;These gems might have been added during the development process. To sort them, enter visual mode, highlight the desired range, and enter &lt;code&gt;:sort&lt;/code&gt;. Here&amp;rsquo;s the result:&lt;/p&gt;</description></item><item><title>Parameters Filtering</title><link>https://jakeworth.com/tils/parameters-filtering/</link><pubDate>Sat, 02 May 2015 15:16:47 -0500</pubDate><guid>https://jakeworth.com/tils/parameters-filtering/</guid><description>&lt;p&gt;Rails logs your server&amp;rsquo;s activity, which is useful for development and debugging. However, often the server handles sensitive information that should not be logged.&lt;/p&gt;
&lt;p&gt;A few examples are authentication credentials, personal data, and financial information.&lt;/p&gt;
&lt;p&gt;To prevent Rails from logging such data, add this to your application configuration:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;config&lt;span style="color:#f92672"&gt;.&lt;/span&gt;filter_parameters &lt;span style="color:#f92672"&gt;&amp;lt;&amp;lt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;:sensitive_param&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;When the named parameter is handled by the server, it will be logged as &lt;code&gt;[FILTERED]&lt;/code&gt; instead of its actual value. Add this configuration by environment if you want to keep the parameters unfiltered in development.&lt;/p&gt;</description></item><item><title>Modify Attribute on Set</title><link>https://jakeworth.com/tils/modify-attribute-on-set/</link><pubDate>Sat, 02 May 2015 15:12:39 -0500</pubDate><guid>https://jakeworth.com/tils/modify-attribute-on-set/</guid><description>&lt;p&gt;In this example, we want to allow users to enter a twitter handle with or without an at-sign (&amp;rsquo;@&amp;rsquo;), just like Twitter, but save it without the at-sign. &lt;code&gt;twitter_handle&lt;/code&gt; is already an attribute on the class.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;class&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;User&lt;/span&gt; &lt;span style="color:#f92672"&gt;&amp;lt;&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;ActiveRecord&lt;/span&gt;&lt;span style="color:#f92672"&gt;::&lt;/span&gt;&lt;span style="color:#66d9ef"&gt;Base&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;def&lt;/span&gt; &lt;span style="color:#a6e22e"&gt;twitter_handle&lt;/span&gt;&lt;span style="color:#f92672"&gt;=&lt;/span&gt;(handle)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; write_attribute(&lt;span style="color:#e6db74"&gt;:twitter_handle&lt;/span&gt;, handle&lt;span style="color:#f92672"&gt;.&lt;/span&gt;to_s&lt;span style="color:#f92672"&gt;.&lt;/span&gt;gsub(&lt;span style="color:#e6db74"&gt;/^@/&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;&amp;#39;&amp;#39;&lt;/span&gt;))
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#66d9ef"&gt;end&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Undo a Git Mistake</title><link>https://jakeworth.com/tils/undo-a-git-mistake/</link><pubDate>Tue, 21 Apr 2015 15:25:51 -0400</pubDate><guid>https://jakeworth.com/tils/undo-a-git-mistake/</guid><description>&lt;p&gt;&lt;code&gt;git reflog&lt;/code&gt; is a record of your actions in Git. With this command, you can undo almost any Git mistake.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;$ git reflog
4bd0090 HEAD@{0}: &amp;lt;bad place&amp;gt;
46bd839 HEAD@{1}: &amp;lt;bad place&amp;gt;
967e214 HEAD@{2}: &amp;lt;last good place&amp;gt;
46bd839 HEAD@{3}: &amp;lt;good place&amp;gt;
967e214 HEAD@{4}: &amp;lt;good place&amp;gt;
$ git reset --hard HEAD@{2}
&lt;/code&gt;&lt;/pre&gt;</description></item><item><title>Delete Comments</title><link>https://jakeworth.com/tils/delete-comments/</link><pubDate>Sat, 18 Apr 2015 14:05:39 -0500</pubDate><guid>https://jakeworth.com/tils/delete-comments/</guid><description>&lt;p&gt;&lt;code&gt;:g/^\s*#/d&lt;/code&gt; will remove comment lines from a file with Vim.&lt;/p&gt;</description></item><item><title>Less Help</title><link>https://jakeworth.com/tils/less-help/</link><pubDate>Thu, 16 Apr 2015 17:04:56 -0500</pubDate><guid>https://jakeworth.com/tils/less-help/</guid><description>&lt;p&gt;While in less (terminal pager program), &lt;code&gt;h&lt;/code&gt; or &lt;code&gt;H&lt;/code&gt; brings up a summary of commands.&lt;/p&gt;</description></item><item><title>How Rails Action Name Works</title><link>https://jakeworth.com/tils/how-rails-action-name-works/</link><pubDate>Mon, 10 Nov 2014 11:04:17 -0500</pubDate><guid>https://jakeworth.com/tils/how-rails-action-name-works/</guid><description>&lt;p&gt;Today I was trying to control what rendered on a page based on which controller
action called it, and discovered the &lt;code&gt;action_name&lt;/code&gt; method. It&amp;rsquo;s located in
&lt;code&gt;actionview&lt;/code&gt;:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pry&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; method(&lt;span style="color:#e6db74"&gt;:action_name&lt;/span&gt;)&lt;span style="color:#f92672"&gt;.&lt;/span&gt;source_location
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#f92672"&gt;[&lt;/span&gt;&lt;span style="color:#e6db74"&gt;&amp;#34;/Users/jake/.rvm/gems/ruby-2.2.3/gems/actionview-4.2.4/lib/action_view/helpers/controller_helper.rb&amp;#34;&lt;/span&gt;, &lt;span style="color:#ae81ff"&gt;10&lt;/span&gt;&lt;span style="color:#f92672"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Add this to your view code, and it you&amp;rsquo;ll get the relevant action:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pry&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; action_name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;index&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Same partial, different context:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;pry&lt;span style="color:#f92672"&gt;&amp;gt;&lt;/span&gt; action_name
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;=&amp;gt;&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#34;drafts&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;This method would allow conditionals like this (written in HAML):&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" style="color:#f8f8f2;background-color:#272822;-moz-tab-size:4;-o-tab-size:4;tab-size:4;-webkit-text-size-adjust:none;"&gt;&lt;code class="language-ruby" data-lang="ruby"&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;if&lt;/span&gt; action_name &lt;span style="color:#f92672"&gt;==&lt;/span&gt; &lt;span style="color:#e6db74"&gt;&amp;#39;index&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;Welcome&lt;/span&gt; to the index&lt;span style="color:#f92672"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;&lt;span style="color:#f92672"&gt;-&lt;/span&gt; &lt;span style="color:#66d9ef"&gt;else&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt; &lt;span style="color:#66d9ef"&gt;Welcome&lt;/span&gt; to the drafts&lt;span style="color:#f92672"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/controller_helper.rb#L10"&gt;https://github.com/rails/rails/blob/master/actionview/lib/action_view/helpers/controller_helper.rb#L10&lt;/a&gt;&lt;/p&gt;</description></item></channel></rss>