<?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>Jake Worth</title><link>https://jakeworth.com/</link><description>Recent content 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, 10 Jul 2026 12:04:19 -0400</lastBuildDate><atom:link href="https://jakeworth.com/index.xml" rel="self" type="application/rss+xml"/><item><title>Start Here</title><link>https://jakeworth.com/start-here/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jakeworth.com/start-here/</guid><description>&lt;p&gt;If you&amp;rsquo;re new to this blog, these are the posts I&amp;rsquo;d start with. They capture the
ideas I return to most often when thinking about writing software and working
effectively as an engineer.&lt;/p&gt;</description></item><item><title>About</title><link>https://jakeworth.com/about/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jakeworth.com/about/</guid><description>&lt;img
src="https://gravatar.com/avatar/fd09cafa089e3aca230986b97da6040e2c3c0f98376e9c04dc232aa588ce6979?s=240"
width="120"
height="120"
alt="Jake's profile"
/&gt;
&lt;p&gt;Hi there! I&amp;rsquo;m Jake.&lt;/p&gt;
&lt;p&gt;My mission is to empower and propel growing businesses with thoughtful,
high-quality software solutions.&lt;/p&gt;
&lt;p&gt;I&amp;rsquo;m a senior software engineer and engineering leader with over a decade of
experience building and shipping software in small, high-trust teams. I learn in
public, write every day, and focus on making both systems and people better
through continuous improvement.&lt;/p&gt;
&lt;p&gt;As a leader, I cut through ambiguity by asking curious, pointed questions that
move projects directly toward shipping. I&amp;rsquo;m known for making hard problems feel
easier by exposing scope and breaking work down into manageable pieces.&lt;/p&gt;</description></item><item><title>Consulting</title><link>https://jakeworth.com/consulting/</link><pubDate>Mon, 29 Jun 2026 00:00:00 +0000</pubDate><guid>https://jakeworth.com/consulting/</guid><description>&lt;p&gt;After more than a decade in the field as an engineering leader and hands-on
practitioner, I&amp;rsquo;m thrilled to be offering a consulting service.&lt;/p&gt;
&lt;p&gt;I am a strong contributor in three areas: technical consulting, mentorship, and
workshops &amp;amp; teaching.&lt;/p&gt;
&lt;h3 id="technical-consulting"&gt;Technical consulting&lt;/h3&gt;
&lt;p&gt;I love digging into tough problems in greenfield and legacy code. A few things
I&amp;rsquo;m good at:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Raising code quality (tooling, testing, monitoring &amp;amp; observability, building
CI/CD pipelines)&lt;/li&gt;
&lt;li&gt;Big scary bugs&lt;/li&gt;
&lt;li&gt;Process improvement&lt;/li&gt;
&lt;li&gt;Internal/external communication and meeting/ceremony refinement&lt;/li&gt;
&lt;li&gt;Refactoring&lt;/li&gt;
&lt;li&gt;Complex feature building&lt;/li&gt;
&lt;li&gt;Requirements gathering and story-carding&lt;/li&gt;
&lt;li&gt;Pair programming, code reviews, and hands-on coaching&lt;/li&gt;
&lt;li&gt;Technical writing and documentation modernization&lt;/li&gt;
&lt;/ul&gt;
&lt;h3 id="mentorship"&gt;Mentorship&lt;/h3&gt;
&lt;p&gt;I have mentored dozens of software engineers. I love listening and helping
people get better! My mentees are successful software engineers across the
industry. I can meet on your schedule and cadence.&lt;/p&gt;</description></item><item><title>Projects &amp; Talks</title><link>https://jakeworth.com/projects-and-talks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jakeworth.com/projects-and-talks/</guid><description>&lt;h2 id="projects"&gt;Projects&lt;/h2&gt;
&lt;p&gt;One of my goals is to launch at least one new project every year. I&amp;rsquo;m making
small bets and staying comfortable with failure.&lt;/p&gt;
&lt;h3 id="2026"&gt;2026&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/jwworth/yes-its-a-problem"&gt;Yes, It&amp;rsquo;s a Problem&lt;/a&gt;: An
OpenAI-powered hobby application that confirms all your fears.&lt;/p&gt;
&lt;figure&gt;&lt;a href="https://github.com/jwworth/yes-its-a-problem"&gt;
&lt;img loading="lazy" src="https://jakeworth.com/images/yiap.png"
alt="Yes, It&amp;#39;s a Problem" height="280"/&gt; &lt;/a&gt;
&lt;/figure&gt;
&lt;h3 id="2025"&gt;2025&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://jwworth.gumroad.com/l/dont-stay-stuck"&gt;Don&amp;rsquo;t Stay Stuck: A Debugging Guide for Rising Engineers&lt;/a&gt;.
Debugging is one of the most difficult programming skills. It&amp;rsquo;s also a skill you
can learn, and that&amp;rsquo;s the purpose of this guide.&lt;/p&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>Genuinely Care</title><link>https://jakeworth.com/posts/genuinely-care/</link><pubDate>Mon, 29 Jun 2026 10:24:22 -0400</pubDate><guid>https://jakeworth.com/posts/genuinely-care/</guid><description>&lt;p&gt;I often reflect on a conversation from years ago with a former Army boss. It&amp;rsquo;s
foundational to how I understand leadership. He said that being a leader means
you have to &amp;ldquo;Genuinely care.&amp;rdquo;&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>Leave a Trace</title><link>https://jakeworth.com/posts/leave-a-trace/</link><pubDate>Thu, 18 Jun 2026 10:40:18 -0400</pubDate><guid>https://jakeworth.com/posts/leave-a-trace/</guid><description>&lt;p&gt;Always leave something behind. If you find something interesting, leave a trace
that you were there.&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>You Learn a Codebase by Changing It</title><link>https://jakeworth.com/posts/you-learn-a-codebase-by-changing-it/</link><pubDate>Thu, 28 May 2026 14:26:41 -0400</pubDate><guid>https://jakeworth.com/posts/you-learn-a-codebase-by-changing-it/</guid><description>&lt;p&gt;How do I &amp;ldquo;get up to speed&amp;rdquo; in a new codebase? Changing it.&lt;/p&gt;</description></item><item><title>Avoid Hasty Caching</title><link>https://jakeworth.com/posts/avoid-hasty-caching/</link><pubDate>Tue, 26 May 2026 15:00:01 -0400</pubDate><guid>https://jakeworth.com/posts/avoid-hasty-caching/</guid><description>&lt;p&gt;Approach caching with caution.&lt;/p&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>Become a Product-First Software Engineer</title><link>https://jakeworth.com/posts/become-a-product-first-software-engineer/</link><pubDate>Fri, 01 May 2026 10:00:45 -0400</pubDate><guid>https://jakeworth.com/posts/become-a-product-first-software-engineer/</guid><description>&lt;p&gt;I think many engineers would be better contributors if they started to think more about the customer impact of their work.&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>AI Policy</title><link>https://jakeworth.com/ai-policy/</link><pubDate>Wed, 29 Apr 2026 00:00:00 +0000</pubDate><guid>https://jakeworth.com/ai-policy/</guid><description>&lt;p&gt;This page summarizes my usage of LLMs (&amp;ldquo;AI&amp;rdquo;) on this website.&lt;/p&gt;</description></item><item><title>On commenting and approving pull requests</title><link>https://jakeworth.com/posts/on-commenting-and-approving-pull-requests/</link><pubDate>Wed, 22 Apr 2026 11:06:20 -0400</pubDate><guid>https://jakeworth.com/posts/on-commenting-and-approving-pull-requests/</guid><description>&lt;p&gt;After reviewing a lot of pull requests, I&amp;rsquo;ve settled on a simple default: if my comments are all nitpicks, suggestions, questions, or non-blocking issues, I leave them and approve the PR at the same time.&lt;/p&gt;</description></item><item><title>Incremental Dependency Upgrades</title><link>https://jakeworth.com/posts/incremental-dependency-upgrades/</link><pubDate>Mon, 20 Apr 2026 17:20:05 -0400</pubDate><guid>https://jakeworth.com/posts/incremental-dependency-upgrades/</guid><description>&lt;p&gt;When possible, I prefer to upgrade dependencies incrementally rather than making
several version jumps. So, we try not to go from React 16 to 19. We go from 16
to 17, then to 18, and finally to 19.&lt;/p&gt;
&lt;h3 id="the-risks-of-jumping-multiple-versions"&gt;The Risks of Jumping Multiple Versions&lt;/h3&gt;
&lt;p&gt;It&amp;rsquo;s very tempting to jump to the latest release. It feels like time travel;
putting your application on the latest in the fewest number of steps. What’s not
to like?&lt;/p&gt;</description></item><item><title>Dependencies Go Forward</title><link>https://jakeworth.com/posts/dependencies-go-forward/</link><pubDate>Mon, 20 Apr 2026 17:12:04 -0400</pubDate><guid>https://jakeworth.com/posts/dependencies-go-forward/</guid><description>&lt;p&gt;A policy I favor with dependency management: go forward. Going backward is an
exception that we must plan to remedy.&lt;/p&gt;
&lt;h3 id="example"&gt;Example&lt;/h3&gt;
&lt;p&gt;Consider a CVE in a dependency at version 5.0 (v5.0). We’re advised that v6.0
and v4.0 are safe. Which way should we go, forward or backward?&lt;/p&gt;
&lt;p&gt;We want to default to forward. Even if we&amp;rsquo;ve been on v4.0 before and know it is
compatible. Even if we aren’t sure that v6.0 is &amp;ldquo;solid&amp;rdquo; or if it takes some code
changes to implement.&lt;/p&gt;</description></item><item><title>Catastrophic Mistakes Are a Team Failure</title><link>https://jakeworth.com/posts/catastrophic-mistakes-are-a-team-failure/</link><pubDate>Mon, 20 Apr 2026 12:11:33 -0400</pubDate><guid>https://jakeworth.com/posts/catastrophic-mistakes-are-a-team-failure/</guid><description>&lt;p&gt;If people can make catastrophic mistakes on your team, the process is broken.&lt;/p&gt;</description></item><item><title>CI/CD and Engineer Morale</title><link>https://jakeworth.com/posts/ci-cd-and-engineer-morale/</link><pubDate>Mon, 20 Apr 2026 11:41:19 -0400</pubDate><guid>https://jakeworth.com/posts/ci-cd-and-engineer-morale/</guid><description>&lt;p&gt;Why do software teams push continuous deployment so strongly? One of the most
important and least discussed reasons is engineer morale.&lt;/p&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>Tradeoffs of Permanently Forking a Library</title><link>https://jakeworth.com/posts/permanently-forking-a-library-tradeoffs/</link><pubDate>Fri, 03 Apr 2026 15:54:06 -0400</pubDate><guid>https://jakeworth.com/posts/permanently-forking-a-library-tradeoffs/</guid><description>&lt;p&gt;Permanently forking a library is something I&amp;rsquo;ve observed on several teams. But, there are tradeoffs that aren&amp;rsquo;t always obvious.&lt;/p&gt;</description></item><item><title>A Missing README Isn't a Missing README</title><link>https://jakeworth.com/posts/a-missing-readme-isnt-a-missing-readme/</link><pubDate>Sun, 29 Mar 2026 09:32:47 -0400</pubDate><guid>https://jakeworth.com/posts/a-missing-readme-isnt-a-missing-readme/</guid><description>&lt;p&gt;A missing README is rarely just missing documentation. It usually signals other
things, too.&lt;/p&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>Better Developer Experience With Friday Reboots</title><link>https://jakeworth.com/posts/better-dev-exp-with-friday-reboots/</link><pubDate>Wed, 11 Mar 2026 09:57:50 -0400</pubDate><guid>https://jakeworth.com/posts/better-dev-exp-with-friday-reboots/</guid><description>&lt;p&gt;A developer experience practice I&amp;rsquo;ve recently picked up is routine Friday reboots of my workstation. I think this can make your workflow (and even perhaps your life as an engineer?) a little better.&lt;/p&gt;</description></item><item><title>How I Run a Fully-Remote Software Engineering Standup</title><link>https://jakeworth.com/posts/how-i-run-a-software-engineering-standup/</link><pubDate>Wed, 04 Mar 2026 10:31:38 -0500</pubDate><guid>https://jakeworth.com/posts/how-i-run-a-software-engineering-standup/</guid><description>&lt;p&gt;I&amp;rsquo;ve been participating in fully-remote software standups every day for over a decade, and over the past two years, leading them, too. Here&amp;rsquo;s how I run the best standup meetings that I can.&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>How I Read 44 Books Last Year</title><link>https://jakeworth.com/posts/how-i-read-44-books-last-year/</link><pubDate>Tue, 24 Feb 2026 16:10:54 -0500</pubDate><guid>https://jakeworth.com/posts/how-i-read-44-books-last-year/</guid><description>&lt;p&gt;Do you want to read more? Over a decade, I&amp;rsquo;ve been on a journey from casual to power-reader. In this post, I&amp;rsquo;d like to share the ideas and techniques that have helped me read more.&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>Favorite Ideas from "It Doesn't Have to Be Crazy at Work"</title><link>https://jakeworth.com/posts/favorite-ideas-from-idhtbcaw/</link><pubDate>Fri, 20 Feb 2026 08:40:45 -0500</pubDate><guid>https://jakeworth.com/posts/favorite-ideas-from-idhtbcaw/</guid><description>&lt;p&gt;I recently re-read &lt;em&gt;It Doesn&amp;rsquo;t Have to be Crazy at Work&lt;/em&gt; by Jason Fried and David Heinemeier of Basecamp. Here are some of my favorite ideas.&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>"What's Wrong With This Idea?"</title><link>https://jakeworth.com/posts/whats-wrong-with-this-idea/</link><pubDate>Wed, 11 Feb 2026 09:43:43 -0500</pubDate><guid>https://jakeworth.com/posts/whats-wrong-with-this-idea/</guid><description>&lt;p&gt;One of my favorite problem-solving questions is: &amp;ldquo;What&amp;rsquo;s wrong with this idea?&amp;rdquo; It drives the conversation away from why the idea might work, and toward why it might fail. That perspective is invaluable when building.&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>Things I Check Before Opening a PR</title><link>https://jakeworth.com/posts/things-i-check-before-opening-a-pr/</link><pubDate>Sat, 07 Feb 2026 14:58:34 -0500</pubDate><guid>https://jakeworth.com/posts/things-i-check-before-opening-a-pr/</guid><description>&lt;p&gt;What is a programmer but a series of PRs (pull requests)? I optimize PRs to
introduce the best code I can, be easy to review, and document my work so I can
make sense of it in the future. Here are some things I always check before
opening a PR.&lt;/p&gt;</description></item><item><title>Why sleep Is Risky in Production Code</title><link>https://jakeworth.com/posts/why-we-discourage-sleep/</link><pubDate>Thu, 05 Feb 2026 08:00:51 -0500</pubDate><guid>https://jakeworth.com/posts/why-we-discourage-sleep/</guid><description>&lt;p&gt;You might have heard that using blocking, waiting code, &lt;em&gt;e.g.&lt;/em&gt;, &lt;code&gt;sleep&lt;/code&gt; in many
languages, is discouraged. Why?&lt;/p&gt;</description></item><item><title>How to Unabstract an Abstraction</title><link>https://jakeworth.com/posts/how-to-unabstract-an-abstraction/</link><pubDate>Sun, 01 Feb 2026 12:46:52 -0500</pubDate><guid>https://jakeworth.com/posts/how-to-unabstract-an-abstraction/</guid><description>&lt;p&gt;Abstractions in code are easy to add and challenging to remove. Sometimes we feel stuck with them. But the good news is, you can back out of almost any abstraction with the right mindset.&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>Building with MCP, for Real</title><link>https://jakeworth.com/posts/building-with-mcp-for-real/</link><pubDate>Fri, 23 Jan 2026 09:23:29 -0500</pubDate><guid>https://jakeworth.com/posts/building-with-mcp-for-real/</guid><description>&lt;p&gt;This year I built several Model Context Protocol (MCP) servers to support ongoing R&amp;amp;D. Here&amp;rsquo;s my report.&lt;/p&gt;</description></item><item><title>Learning to Program in 2026</title><link>https://jakeworth.com/posts/learning-to-program-in-2026/</link><pubDate>Fri, 16 Jan 2026 12:00:19 -0500</pubDate><guid>https://jakeworth.com/posts/learning-to-program-in-2026/</guid><description>&lt;p&gt;If I had to start over as a person who wanted to become a professional programmer, in 2026, what would I do?&lt;/p&gt;</description></item><item><title>Things I Don't Know, As of 2026</title><link>https://jakeworth.com/posts/things-i-dont-know-as-of-2026/</link><pubDate>Tue, 13 Jan 2026 11:25:29 -0500</pubDate><guid>https://jakeworth.com/posts/things-i-dont-know-as-of-2026/</guid><description>&lt;p&gt;Here&amp;rsquo;s a list of the things that I&amp;rsquo;d like to learn about and have chosen not to specialize in (yet), as of 2026.&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>Getting It Right the First Time</title><link>https://jakeworth.com/posts/getting-it-right-the-first-time/</link><pubDate>Mon, 05 Jan 2026 07:51:03 -0500</pubDate><guid>https://jakeworth.com/posts/getting-it-right-the-first-time/</guid><description>&lt;p&gt;There&amp;rsquo;s an enviable quality of great engineers I&amp;rsquo;ve known: they seem to get things right the first time. When you ask them to do something, and they say &amp;ldquo;It&amp;rsquo;s done&amp;rdquo;, it is, almost always. How?&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>Running Great Refinement Meetings</title><link>https://jakeworth.com/posts/running-great-refinement-meetings/</link><pubDate>Mon, 01 Dec 2025 11:18:17 -0500</pubDate><guid>https://jakeworth.com/posts/running-great-refinement-meetings/</guid><description>&lt;p&gt;This year I&amp;rsquo;ve run over 25 Scrum refinement meetings; here&amp;rsquo;s what I&amp;rsquo;ve learned.&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>User Manual</title><link>https://jakeworth.com/user-manual/</link><pubDate>Thu, 13 Nov 2025 09:51:03 -0500</pubDate><guid>https://jakeworth.com/user-manual/</guid><description>&lt;p&gt;Working with me? Awesome! I built this user manual to share my working style and communication preferences.&lt;/p&gt;
&lt;p&gt;For those interested in building their own user manual, here&amp;rsquo;s &lt;a href="https://www.atlassian.com/team-playbook/plays/my-user-manual"&gt;the guide&lt;/a&gt; that helped me.&lt;/p&gt;
&lt;h3 id="work"&gt;Work&lt;/h3&gt;
&lt;h4 id="what-is-your-work-and-life-setup"&gt;What is your work and life setup?&lt;/h4&gt;
&lt;p&gt;I start work at 9 AM EST. As a team lead, I have a morning routine that includes focusing my day&amp;rsquo;s priorities, reviewing PR&amp;rsquo;s and tickets, moving my personal tickets work forward, reading emails, and following up on requests that I&amp;rsquo;ve made.&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>Prioritization for Engineers: Rank Every Work List</title><link>https://jakeworth.com/posts/always-be-ranking/</link><pubDate>Thu, 23 Oct 2025 13:46:50 -0400</pubDate><guid>https://jakeworth.com/posts/always-be-ranking/</guid><description>&lt;p&gt;Anytime you&amp;rsquo;re making a list at work, rank it.&lt;/p&gt;</description></item><item><title>Acceptance Criteria That Actually Work</title><link>https://jakeworth.com/posts/acceptance-criteria-that-actually-work/</link><pubDate>Tue, 30 Sep 2025 03:37:56 -0400</pubDate><guid>https://jakeworth.com/posts/acceptance-criteria-that-actually-work/</guid><description>&lt;p&gt;Acceptance criteria, or AC, describe what a feature or bugfix does. Writing them is an art, and some AC work much better than others. So, how do we make them work? By including a little more detail.&lt;/p&gt;</description></item><item><title>Get Better at Debugging by Making Predictions</title><link>https://jakeworth.com/posts/get-better-at-debugging-by-making-predictions/</link><pubDate>Tue, 23 Sep 2025 10:16:28 -0400</pubDate><guid>https://jakeworth.com/posts/get-better-at-debugging-by-making-predictions/</guid><description>&lt;p&gt;Shift to a proactive mindset by making predictions before any experiments in a debugging session.&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>Raise the "I'm Stuck" Flag</title><link>https://jakeworth.com/posts/raise-the-im-stuck-flag/</link><pubDate>Wed, 10 Sep 2025 14:16:30 -0400</pubDate><guid>https://jakeworth.com/posts/raise-the-im-stuck-flag/</guid><description>&lt;p&gt;Consider this scenario. You&amp;rsquo;ve been given some work, and you&amp;rsquo;re stuck. Hours have become days. You&amp;rsquo;ve exhausted the internet. You&amp;rsquo;re starting to backtrack, delete work, and start over. Feeling defeated. To make matters worse, you haven&amp;rsquo;t told anybody.&lt;/p&gt;</description></item><item><title>Debugging Is a Story</title><link>https://jakeworth.com/posts/debugging-is-a-story/</link><pubDate>Tue, 09 Sep 2025 13:27:03 -0400</pubDate><guid>https://jakeworth.com/posts/debugging-is-a-story/</guid><description>&lt;p&gt;Today I want to talk about a way I think about debugging: as a story that we tell to ourselves and each other.&lt;/p&gt;</description></item><item><title>Learning JavaScript Promises the Feynman Way</title><link>https://jakeworth.com/posts/learning-javascript-promises-the-feynman-way/</link><pubDate>Mon, 25 Aug 2025 12:08:06 -0400</pubDate><guid>https://jakeworth.com/posts/learning-javascript-promises-the-feynman-way/</guid><description>&lt;p&gt;Want to learn a tricky topic and sharpen your learning skills at the same time? In this post, I&amp;rsquo;ll use the Feynman Learning Technique— a method of learning complex things by explaining them simply— with a sprinkle of LLM magic, to deepen my understanding of JavaScript promises.&lt;/p&gt;</description></item><item><title>"Don't Stay Stuck" Digital Guide Launch</title><link>https://jakeworth.com/posts/dont-stay-stuck-digital-guide-launch/</link><pubDate>Tue, 12 Aug 2025 09:33:04 -0400</pubDate><guid>https://jakeworth.com/posts/dont-stay-stuck-digital-guide-launch/</guid><description>&lt;p&gt;I&amp;rsquo;m proud to announce the launch of my digital guide to software debugging, &lt;a href="https://jwworth.gumroad.com/l/dont-stay-stuck"&gt;Don&amp;rsquo;t Stay Stuck: A Debugging Guide for Rising Engineers&lt;/a&gt;!&lt;/p&gt;</description></item><item><title>A Talk on Twelve Factors</title><link>https://jakeworth.com/posts/a-talk-on-12-factors/</link><pubDate>Fri, 01 Aug 2025 13:48:58 -0400</pubDate><guid>https://jakeworth.com/posts/a-talk-on-12-factors/</guid><description>&lt;p&gt;Today I gave a talk to my team about the Twelve-Factor App Methodology.&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>A Kaizen for Knowledge Work</title><link>https://jakeworth.com/posts/we-ran-a-software-engineering-kaizen/</link><pubDate>Wed, 16 Jul 2025 09:00:30 -0400</pubDate><guid>https://jakeworth.com/posts/we-ran-a-software-engineering-kaizen/</guid><description>&lt;p&gt;Confluence was messy. Our documentation felt outdated, hard to navigate, and unreliable. Rather than scrap everything and start over, I decided to try something different: a Kaizen.&lt;/p&gt;</description></item><item><title>Generate the Data. Worry Later.</title><link>https://jakeworth.com/posts/generate-the-data/</link><pubDate>Mon, 07 Jul 2025 11:58:44 -0400</pubDate><guid>https://jakeworth.com/posts/generate-the-data/</guid><description>&lt;p&gt;A suggestion about data: generate it now, and figure out curation later.&lt;/p&gt;</description></item><item><title>Custom Ipsum for Real-World Testing</title><link>https://jakeworth.com/posts/custom-ipsum-for-real-world-testing/</link><pubDate>Fri, 27 Jun 2025 16:00:28 -0400</pubDate><guid>https://jakeworth.com/posts/custom-ipsum-for-real-world-testing/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Pastures which are subject to overflow should be avoided. All lambs born in April or May should be drenched about August or September following, to be certain of ridding them of worms that may later cause their death.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is output from a tool I built called &lt;em&gt;Veterinary Ipsum&lt;/em&gt;. It&amp;rsquo;s something I&amp;rsquo;ve created a few times: a Lorem Ipsum generator specific to my company&amp;rsquo;s business domain.&lt;/p&gt;</description></item><item><title>Banishing "Random" for Better Software Communication</title><link>https://jakeworth.com/posts/nothing-is-random/</link><pubDate>Tue, 17 Jun 2025 12:19:04 -0400</pubDate><guid>https://jakeworth.com/posts/nothing-is-random/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;I&amp;rsquo;m still getting this random 404.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Want to sound pro? Banish &amp;ldquo;random&amp;rdquo; from your software engineering vocabulary.&lt;/p&gt;</description></item><item><title>Why I Write for Software Engineers and Engineering Leaders</title><link>https://jakeworth.com/posts/why-im-writing-to-you/</link><pubDate>Wed, 11 Jun 2025 09:47:19 -0400</pubDate><guid>https://jakeworth.com/posts/why-im-writing-to-you/</guid><description>&lt;p&gt;Eight years ago I wrote a post called &lt;a href="https://www.jakeworth.com/posts/you-should-blog"&gt;You Should Blog&lt;/a&gt;. In it, I made an argument that I still believe in: public, professional writing is something every engineer should try. Today, I want to share why &lt;em&gt;I&lt;/em&gt; write, and have for over a decade.&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>Four Things I've Changed My Mind About in Engineering</title><link>https://jakeworth.com/posts/things-ive-changed-my-mind-about/</link><pubDate>Thu, 29 May 2025 09:20:14 -0400</pubDate><guid>https://jakeworth.com/posts/things-ive-changed-my-mind-about/</guid><description>&lt;p&gt;I think a mark of a great engineer is being willing to change one&amp;rsquo;s mind when presented with new information. Here are four technological things I&amp;rsquo;ve changed my mind about.&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 I Approach Feature Requests</title><link>https://jakeworth.com/posts/how-i-approach-feature-requests/</link><pubDate>Wed, 14 May 2025 17:40:42 -0400</pubDate><guid>https://jakeworth.com/posts/how-i-approach-feature-requests/</guid><description>&lt;p&gt;Receiving feature requests is part of running a software team. Here&amp;rsquo;s how I handle them.&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>Don't Guess</title><link>https://jakeworth.com/posts/dont-guess/</link><pubDate>Tue, 29 Apr 2025 09:30:56 -0400</pubDate><guid>https://jakeworth.com/posts/dont-guess/</guid><description>&lt;p&gt;This is a response to &amp;ldquo;Don&amp;rsquo;t Guess&amp;rdquo; from the excellent &lt;a href="https://endler.dev/2025/best-programmers/"&gt;&amp;ldquo;The Best Programmers I Know&amp;rdquo;&lt;/a&gt; by Matthias Endler. My goal is to crystallize my understanding of this trait.&lt;/p&gt;</description></item><item><title>Your Software Is Confusing</title><link>https://jakeworth.com/posts/your-software-is-confusing/</link><pubDate>Mon, 07 Apr 2025 10:16:44 -0400</pubDate><guid>https://jakeworth.com/posts/your-software-is-confusing/</guid><description>&lt;p&gt;If something in your software is confusing to a customer, it &lt;em&gt;is&lt;/em&gt; confusing.&lt;/p&gt;</description></item><item><title>Why I'm "All In" on TypeScript</title><link>https://jakeworth.com/posts/why-im-all-in-on-typescript/</link><pubDate>Wed, 26 Mar 2025 10:47:45 -0400</pubDate><guid>https://jakeworth.com/posts/why-im-all-in-on-typescript/</guid><description>&lt;p&gt;I&amp;rsquo;ve added TypeScript to several projects I&amp;rsquo;ve worked on. In this post, I&amp;rsquo;d like to discuss why I think TypeScript is essential and document my expectations around it.&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>Two-Follow-Up Rule for Closing Support and Internal Tickets</title><link>https://jakeworth.com/posts/hit-it-twice/</link><pubDate>Tue, 04 Mar 2025 09:28:10 -0500</pubDate><guid>https://jakeworth.com/posts/hit-it-twice/</guid><description>&lt;p&gt;I recently learned a practice for customer communication that I&amp;rsquo;d like to document. It&amp;rsquo;s called &amp;ldquo;Hit It Twice.&amp;rdquo;&lt;/p&gt;</description></item><item><title>It's Tradeoffs All the Way Down</title><link>https://jakeworth.com/posts/its-tradeoffs-all-the-way-down/</link><pubDate>Wed, 19 Feb 2025 10:11:37 -0400</pubDate><guid>https://jakeworth.com/posts/its-tradeoffs-all-the-way-down/</guid><description>&lt;p&gt;One common trait among early-career programmers is seeing technology choices in black-and-white. I&amp;rsquo;ve been there. &amp;ldquo;Redux is awesome!&amp;rdquo; &amp;ldquo;Nested ternaries are terrible!&amp;rdquo; As you advance as a programmer, for better or worse, you start to see almost everything as a trade-off.&lt;/p&gt;</description></item><item><title>"I Don't Understand" Debugging</title><link>https://jakeworth.com/posts/i-dont-understand-debugging/</link><pubDate>Thu, 13 Feb 2025 09:52:51 -0400</pubDate><guid>https://jakeworth.com/posts/i-dont-understand-debugging/</guid><description>&lt;p&gt;My definition of &amp;ldquo;I don&amp;rsquo;t understand&amp;rdquo; debugging.&lt;/p&gt;</description></item><item><title>How to Start a Meetup Group (Lessons from Running One for 10 Years)</title><link>https://jakeworth.com/posts/how-i-organize-a-meetup/</link><pubDate>Mon, 03 Feb 2025 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-i-organize-a-meetup/</guid><description>&lt;p&gt;I&amp;rsquo;ve been organizing Meetups for a decade, starting with Vim Chicago and Chicago Elixir, and now running &lt;a href="https://mainejs.org/"&gt;Maine JS&lt;/a&gt; from Portland, Maine. In honor of our most recent Meetup, here&amp;rsquo;s my practical guide on how to start a Meetup group, based on what&amp;rsquo;s worked for me.&lt;/p&gt;</description></item><item><title>My Annual Review 2024</title><link>https://jakeworth.com/posts/my-annual-review-2024/</link><pubDate>Tue, 31 Dec 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/my-annual-review-2024/</guid><description>&lt;p&gt;Here&amp;rsquo;s my annual review covering 2024.&lt;/p&gt;</description></item><item><title>Hard-Won Software Development Habits</title><link>https://jakeworth.com/posts/hard-won-software-development-habits/</link><pubDate>Wed, 27 Nov 2024 10:19:47 -0400</pubDate><guid>https://jakeworth.com/posts/hard-won-software-development-habits/</guid><description>&lt;p&gt;This post is about how to write software well. It was inspired by &lt;a href="https://zarar.dev/good-software-development-habits/"&gt;this post&lt;/a&gt; with a similar title. Read it and write yours.&lt;/p&gt;</description></item><item><title>Ship Earlier to Learn What Matters</title><link>https://jakeworth.com/posts/we-should-take-this-outside/</link><pubDate>Sun, 24 Nov 2024 10:16:49 -0400</pubDate><guid>https://jakeworth.com/posts/we-should-take-this-outside/</guid><description>&lt;p&gt;TONY: We should take this outside.&lt;/p&gt;</description></item><item><title>Being the Third Engineer</title><link>https://jakeworth.com/posts/being-the-third-engineer/</link><pubDate>Wed, 16 Oct 2024 13:37:01 -0400</pubDate><guid>https://jakeworth.com/posts/being-the-third-engineer/</guid><description>&lt;p&gt;I was the third engineer hired by my company, not counting our technical co-founder. I like that position, and it seems to play to my strengths.&lt;/p&gt;</description></item><item><title>Getting Comfortable With Discomfort in Software Engineering</title><link>https://jakeworth.com/posts/comfort-with-discomfort/</link><pubDate>Tue, 03 Sep 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/comfort-with-discomfort/</guid><description>&lt;p&gt;Today I&amp;rsquo;d like to talk about a quality that&amp;rsquo;s essential to success as a computer programmer. Let&amp;rsquo;s call it &amp;ldquo;comfort with discomfort.&amp;rdquo; As programmers, we live in this unsettling space. Here are some thoughts on discomfort and tips for dealing with it skillfully.&lt;/p&gt;</description></item><item><title>Decoupling Design From Engineering</title><link>https://jakeworth.com/posts/decoupling-design-from-engineering/</link><pubDate>Thu, 29 Aug 2024 11:55:49 -0400</pubDate><guid>https://jakeworth.com/posts/decoupling-design-from-engineering/</guid><description>&lt;p&gt;Often, when you work as an engineer on a small team, you don&amp;rsquo;t have dedicated designers on staff. How can you deliver beautiful, intuitive software without designers? Here&amp;rsquo;s a trick that helps me: decoupling my design work from my engineering work.&lt;/p&gt;</description></item><item><title>The Secret to Being a 10x Engineer</title><link>https://jakeworth.com/posts/the-secret-to-being-a-10x-engineer/</link><pubDate>Fri, 26 Jul 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/the-secret-to-being-a-10x-engineer/</guid><description>&lt;p&gt;Our industry has a concept of &amp;ldquo;10x engineers&amp;rdquo;, individual contributors who have
the impact of ten colleagues. How can you become one? I&amp;rsquo;ll try to answer that
in this post.&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>Find Every Debugging Trail Marker</title><link>https://jakeworth.com/posts/dont-skip-debugging-steps/</link><pubDate>Mon, 17 Jun 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/dont-skip-debugging-steps/</guid><description>&lt;p&gt;If you&amp;rsquo;ve ever watched me debug, you might think I&amp;rsquo;m moving slowly. That&amp;rsquo;s
because I try hard to find every marker on the debugging trail. I believe this
is one of the most valuable skills in debugging.&lt;/p&gt;</description></item><item><title>How I Review Code, Part 2</title><link>https://jakeworth.com/posts/how-i-review-code-pt-2/</link><pubDate>Thu, 06 Jun 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-i-review-code-pt-2/</guid><description>&lt;p&gt;Reviewing code is tricky. When I&amp;rsquo;m doing it, I&amp;rsquo;m trying to achieve a few things
at once. In this post, I&amp;rsquo;d like to document the ways I try to add value via
code reviews.&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>How to Deliver Code Every Day</title><link>https://jakeworth.com/posts/how-to-deliver-code-every-day/</link><pubDate>Thu, 15 Feb 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-to-deliver-code-every-day/</guid><description>&lt;p&gt;I recently calculated that I merge 0.8 pull requests every day into my team
repo. Let&amp;rsquo;s round up and say I merge about one PR every day, delivering one or
more features to production. I like this velocity, and in this post, I&amp;rsquo;ll
explain how you can achieve it yourself.&lt;/p&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>Practical Ways to 'Learn in Public' Now</title><link>https://jakeworth.com/posts/practical-ways-to-learn-in-public-now/</link><pubDate>Sun, 28 Jan 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/practical-ways-to-learn-in-public-now/</guid><description>&lt;p&gt;I&amp;rsquo;ve been a practitioner of Shawn Wang&amp;rsquo;s &lt;a href="https://www.swyx.io/learn-in-public"&gt;&amp;lsquo;Learn in Public&amp;rsquo;&lt;/a&gt; for years.
In this post, I&amp;rsquo;ll share a list of ways I&amp;rsquo;ve found to learn in public.&lt;/p&gt;</description></item><item><title>Reflections on Ten Years Professionally Programming</title><link>https://jakeworth.com/posts/reflections-on-ten-years-professsionally-programming/</link><pubDate>Tue, 09 Jan 2024 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/reflections-on-ten-years-professsionally-programming/</guid><description>&lt;p&gt;I recently hit a decade of professional programming. I&amp;rsquo;d like to take
a moment here and reflect on what I&amp;rsquo;ve learned.&lt;/p&gt;</description></item><item><title>My Annual Review 2023</title><link>https://jakeworth.com/posts/my-annual-review-2023/</link><pubDate>Thu, 28 Dec 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/my-annual-review-2023/</guid><description>&lt;p&gt;Here&amp;rsquo;s my annual professional review covering 2023.&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>Master the Fundamentals First</title><link>https://jakeworth.com/posts/you-cant-be-looking-up-map/</link><pubDate>Thu, 07 Dec 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/you-cant-be-looking-up-map/</guid><description>&lt;p&gt;When I was learning to program, I was fortunate to pair with very experienced
engineers. One day while coding, I said: &amp;ldquo;I think we need to use Ruby&amp;rsquo;s &lt;code&gt;map&lt;/code&gt;
method, but I&amp;rsquo;m not sure how that works. Let me look it up.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;Later, my pair offered some feedback: &amp;ldquo;You can&amp;rsquo;t be looking up &lt;code&gt;map&lt;/code&gt;. You need
to know how all of Ruby&amp;rsquo;s Enumerable methods work.&amp;rdquo;&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>"What Would Finishing This Today Look Like?"</title><link>https://jakeworth.com/posts/what-would-finishing-this-today-look-like/</link><pubDate>Thu, 09 Nov 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/what-would-finishing-this-today-look-like/</guid><description>&lt;p&gt;When I don&amp;rsquo;t feel like I&amp;rsquo;m making sufficient progress at work, I have a
favorite technique: asking &amp;ldquo;What would finishing this today look like?&amp;rdquo;&lt;/p&gt;</description></item><item><title>Absence Of Color Is Better Than the Wrong Color</title><link>https://jakeworth.com/posts/no-color-is-better-than-the-wrong-color/</link><pubDate>Mon, 06 Nov 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/no-color-is-better-than-the-wrong-color/</guid><description>&lt;p&gt;A design principle that&amp;rsquo;s crept into my programming could be summarized
as:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;Absence of color is better than the wrong color.&amp;rdquo;&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Product Technique: Asking 'What's the Why?'</title><link>https://jakeworth.com/posts/whats-the-why/</link><pubDate>Mon, 30 Oct 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/whats-the-why/</guid><description>&lt;p&gt;One of my favorite product hacks is asking: &amp;ldquo;What&amp;rsquo;s the why?&amp;rdquo;&lt;/p&gt;</description></item><item><title>Write Boring Code</title><link>https://jakeworth.com/posts/write-boring-code/</link><pubDate>Wed, 13 Sep 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/write-boring-code/</guid><description>&lt;p&gt;Write a little bit of code, and you may come to an unsettling realization:
there are multiple ways to do almost any programming task. How do we choose
between several that work? I manage this uncertainty with a guideline: writing
boring code. In this post, I&amp;rsquo;ll try to explain what boring means to me.&lt;/p&gt;</description></item><item><title>Take the Big Project</title><link>https://jakeworth.com/posts/take-the-big-project/</link><pubDate>Wed, 06 Sep 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/take-the-big-project/</guid><description>&lt;p&gt;Something I&amp;rsquo;ve learned as an engineer: when presented with the option of
working on a big project, or doing anything else, take the big project.&lt;/p&gt;</description></item><item><title>Thinking of Bugs in Classes</title><link>https://jakeworth.com/posts/thinking-of-bugs-in-classes/</link><pubDate>Sun, 03 Sep 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/thinking-of-bugs-in-classes/</guid><description>&lt;p&gt;We spent the time writing tests, and yet, a bug survived. Should we just stop
writing tests? No, but we should maybe write better tests, and think about them differently.&lt;/p&gt;</description></item><item><title>Why Great PRs Are Great: Pull Requests Templates</title><link>https://jakeworth.com/posts/pull-request-templates/</link><pubDate>Mon, 14 Aug 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/pull-request-templates/</guid><description>&lt;p&gt;Have you ever seen a pull request that seems to completely explain itself? It&amp;rsquo;s
a real artifact. I don&amp;rsquo;t know the project, yet I understand it. How can we get
results like this on every pull request, from every developer on the team,
every time?&lt;/p&gt;</description></item><item><title>Don't Ask for Advice; Ask for a Code Review</title><link>https://jakeworth.com/posts/dont-ask-for-advice-ask-for-a-code-review/</link><pubDate>Wed, 09 Aug 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/dont-ask-for-advice-ask-for-a-code-review/</guid><description>&lt;p&gt;Here&amp;rsquo;s some advice about programming I&amp;rsquo;ve found useful: &amp;ldquo;Don&amp;rsquo;t ask for advice; ask for a code review.&amp;rdquo; In this post, I&amp;rsquo;d like to explore what I think this adage means.&lt;/p&gt;</description></item><item><title>From Booleans to Strings in Frontend State</title><link>https://jakeworth.com/posts/from-boolean-to-strings-in-frontend-state/</link><pubDate>Fri, 04 Aug 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/from-boolean-to-strings-in-frontend-state/</guid><description>&lt;p&gt;When it comes to controlling frontend presentation, developers often rely on booleans. However, this approach can be limiting. In this post, I’ll explore the drawbacks of using booleans and introduce a more versatile alternative: plain old strings with type safety.&lt;/p&gt;</description></item><item><title>The Case Against "Try This" Debugging</title><link>https://jakeworth.com/posts/the-case-against-try-this-debugging/</link><pubDate>Mon, 26 Jun 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/the-case-against-try-this-debugging/</guid><description>&lt;p&gt;In many group debugging sessions I&amp;rsquo;ve joined, a major technique being
deployed is something I call &amp;ldquo;Try This&amp;rdquo; debugging. In this post, I&amp;rsquo;d like
to talk about this anti-pattern, and consider a better way.&lt;/p&gt;</description></item><item><title>Absolute Imports in TypeScript and React: A Practical Guide</title><link>https://jakeworth.com/posts/the-joy-of-javascript-absolute-imports/</link><pubDate>Tue, 02 May 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/the-joy-of-javascript-absolute-imports/</guid><description>&lt;p&gt;Absolute imports are an essential developer experience feature for me in any JavaScript application. In this post, I&amp;rsquo;ll explain what they are, how to use them, and why they matter.&lt;/p&gt;</description></item><item><title>My Daily Programming Routine as a Senior Software Engineer</title><link>https://jakeworth.com/posts/my-daily-programming-routine/</link><pubDate>Mon, 10 Apr 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/my-daily-programming-routine/</guid><description>&lt;p&gt;Over the past decade, I&amp;rsquo;ve settled into a daily programming routine that helps me stay productive. It centers on code review, moving tickets forward, finishing in-progress work, and documenting what I learn. Here&amp;rsquo;s the exact workflow I use.&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>Variable Name Antipatterns Named and Explained</title><link>https://jakeworth.com/posts/variable-name-antipatterns/</link><pubDate>Mon, 03 Apr 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/variable-name-antipatterns/</guid><description>&lt;blockquote&gt;
&lt;p&gt;There are only two hard things in Computer Science: cache invalidation and
naming things.
&amp;ndash; Phil Karlton&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Let&amp;rsquo;s talk about variable name antipatterns!&lt;/p&gt;</description></item><item><title>Cold Water for Your Code Coverage</title><link>https://jakeworth.com/posts/cold-water-for-your-code-coverage/</link><pubDate>Tue, 28 Mar 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/cold-water-for-your-code-coverage/</guid><description>&lt;p&gt;Code coverage, the percentage of your code covered by automated tests, is a
metric associated with quality. In this post, I&amp;rsquo;d like to investigate this
association. And pour some cold water on it.&lt;/p&gt;</description></item><item><title>Does ChatGPT Mean Software Engineering Is Over?</title><link>https://jakeworth.com/posts/does-chat-gpt-mean-software-engineering-is-over/</link><pubDate>Sun, 26 Mar 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/does-chat-gpt-mean-software-engineering-is-over/</guid><description>&lt;p&gt;Here&amp;rsquo;s an argument that&amp;rsquo;s gaining momentum in my field: AI will eliminate or greatly reduce the programming profession.&lt;/p&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>One-Sentence Summaries of Popular Technology Books</title><link>https://jakeworth.com/posts/one-sentence-summaries-of-popular-technology-books/</link><pubDate>Tue, 21 Mar 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/one-sentence-summaries-of-popular-technology-books/</guid><description>&lt;p&gt;Here are some one-sentence summaries of books that have helped me understand
programming and technology.&lt;/p&gt;</description></item><item><title>How to Run an Agile Retrospective for Leaders</title><link>https://jakeworth.com/posts/how-to-run-an-agile-retrospective-for-leaders/</link><pubDate>Wed, 15 Mar 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-to-run-an-agile-retrospective-for-leaders/</guid><description>&lt;p&gt;Retrospectives are one of my favorite engineering team practices. In this post,
I&amp;rsquo;ll explain why and how I run retros.&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>Type Your TypeScript Library Functions</title><link>https://jakeworth.com/posts/type-your-typescript-library-functions/</link><pubDate>Wed, 01 Mar 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/type-your-typescript-library-functions/</guid><description>&lt;p&gt;There&amp;rsquo;s been a lot of recent discussion in the TypeScript community about
typing functions. These arguments tend to take binary positions: always type
your functions, or never type them unless the compiler demands it. Which is the best option?&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>The Power of CRUD Operations Explained with SQL</title><link>https://jakeworth.com/posts/the-power-of-crud-operations-explained-with-sql/</link><pubDate>Thu, 12 Jan 2023 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/the-power-of-crud-operations-explained-with-sql/</guid><description>&lt;p&gt;CRUD is an acronym that&amp;rsquo;s used a lot in web and mobile development. Frontend
engineers in particular might wonder what it means and why we use it.
In this post, I&amp;rsquo;ll explain CRUD using PostgreSQL, and talk about why it&amp;rsquo;s
important.&lt;/p&gt;</description></item><item><title>How to Create a Timer or Polling in React with setInterval</title><link>https://jakeworth.com/posts/how-to-create-a-simple-timer-in-react-with-setinterval/</link><pubDate>Thu, 29 Dec 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-to-create-a-simple-timer-in-react-with-setinterval/</guid><description>&lt;p&gt;Have you ever wanted to create a timer in a React app? This could be in support
of a UI timer or polling. In this post, I&amp;rsquo;ll explain how to create a timer
effect in a React application using hooks and &lt;code&gt;setInterval&lt;/code&gt;.&lt;/p&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>My Feature Writing Template: Given/When/Then</title><link>https://jakeworth.com/posts/given-when-then/</link><pubDate>Tue, 20 Dec 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/given-when-then/</guid><description>&lt;p&gt;When preparing feature development work, I write Gherkin-style tickets,
which follow the &amp;ldquo;Given/When/Then&amp;rdquo; format. Many people call these stories, and
I do, too. This technique is incredibly effective! But why? In this post, I&amp;rsquo;ll try to answer that question.&lt;/p&gt;</description></item><item><title>Button, Link, or Neither? Three Principles for Clarity and Accessibility</title><link>https://jakeworth.com/posts/button-link-or-neither/</link><pubDate>Sat, 03 Dec 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/button-link-or-neither/</guid><description>&lt;p&gt;Which HTML elements should we be giving a user to click? In this post, I&amp;rsquo;ll
share some best practices for clickable elements.&lt;/p&gt;</description></item><item><title>All My Best Tips For Expertly Reviewing Your Own Code</title><link>https://jakeworth.com/posts/six-tips-for-reviewing-your-own-code/</link><pubDate>Sat, 12 Nov 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/six-tips-for-reviewing-your-own-code/</guid><description>&lt;p&gt;Great developers review their own code often and effectively. In this post, I&amp;rsquo;ll
share a checklist of all my best tips for maximizing this important practice.&lt;/p&gt;</description></item><item><title>Deliver a Great Standup Report as an Engineer</title><link>https://jakeworth.com/posts/deliver-a-great-standup-report-as-an-engineer/</link><pubDate>Wed, 09 Nov 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/deliver-a-great-standup-report-as-an-engineer/</guid><description>&lt;p&gt;I&amp;rsquo;ve been lucky to have worked with some great engineers, and one thing that
they tend to do exceptionally well is reporting about their work at meetings.
Today I&amp;rsquo;d like to summarize what I think makes a great standup report.&lt;/p&gt;</description></item><item><title>How to Write a Resume for Transitioning to Programming</title><link>https://jakeworth.com/posts/resume-for-transitioning-to-programming/</link><pubDate>Thu, 27 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/resume-for-transitioning-to-programming/</guid><description>&lt;p&gt;As a mentor at &lt;a href="https://www.codeplatoon.org/"&gt;Code Platoon&lt;/a&gt;, I&amp;rsquo;ve been able to help many people
transition into programming. In this post, I&amp;rsquo;d like to focus on a vital part of
that process: crafting your transitioning-to-tech resume.&lt;/p&gt;</description></item><item><title>Solving Exercism's Resistor Color Trio in TypeScript</title><link>https://jakeworth.com/posts/resistor-color-trio-in-typescript/</link><pubDate>Wed, 26 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/resistor-color-trio-in-typescript/</guid><description>&lt;p&gt;Today I completed the &amp;lsquo;Resistor Color Trio&amp;rsquo; TypeScript exercise on Exercism. Here&amp;rsquo;s my solution.&lt;/p&gt;</description></item><item><title>Vim Scratchpad Part 2</title><link>https://jakeworth.com/posts/vim-scratchpad-part-2/</link><pubDate>Wed, 26 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/vim-scratchpad-part-2/</guid><description>&lt;p&gt;Today, I&amp;rsquo;d like to dive deeper into a part of my practice: using a persisted
text file for jotting things down. In this post, I&amp;rsquo;ll explain the &amp;lsquo;why&amp;rsquo; behind this technique, and provide an
updated version of it.&lt;/p&gt;</description></item><item><title>Buy the Best Hardware You Can</title><link>https://jakeworth.com/posts/buy-the-best-hardware-you-can/</link><pubDate>Tue, 25 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/buy-the-best-hardware-you-can/</guid><description>&lt;p&gt;Some advice I offer people entering the programming profession is to buy the
best hardware you can. You&amp;rsquo;re going to need it.&lt;/p&gt;</description></item><item><title>Solving Exercism's Resistor Color Duo in TypeScript</title><link>https://jakeworth.com/posts/resistor-color-duo-in-typescript/</link><pubDate>Mon, 24 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/resistor-color-duo-in-typescript/</guid><description>&lt;p&gt;Today as a code kata I completed the &amp;lsquo;Resistor Color Duo&amp;rsquo; TypeScript exercise
on Exercism. Here&amp;rsquo;s my work.&lt;/p&gt;</description></item><item><title>Print Last Exit Code</title><link>https://jakeworth.com/posts/print-last-exit-code/</link><pubDate>Fri, 21 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/print-last-exit-code/</guid><description>&lt;p&gt;The exit code of a command in a Unix-based system is an important and
easy-to-miss piece of data. It isn&amp;rsquo;t printed to standard out; you have
to go looking for it. I find it useful to inspect this information when
debugging or considering chaining unfamiliar commands.&lt;/p&gt;</description></item><item><title>You Can't Change Nothing</title><link>https://jakeworth.com/posts/you-cant-change-nothing/</link><pubDate>Fri, 21 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/you-cant-change-nothing/</guid><description>&lt;p&gt;I saw a meme this week: a person debugging code, &amp;ldquo;My code doesn&amp;rsquo;t work.
Let&amp;rsquo;s change nothing and run it again.&amp;rdquo;&lt;/p&gt;
&lt;p&gt;This is something that I&amp;rsquo;ve done. It seems pointless. But that&amp;rsquo;s not quite correct.&lt;/p&gt;</description></item><item><title>Read the Docs</title><link>https://jakeworth.com/posts/read-the-docs/</link><pubDate>Wed, 19 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/read-the-docs/</guid><description>&lt;p&gt;When learning a new language or framework, the first thing I do is read the
official documentation cover-to-cover.&lt;/p&gt;</description></item><item><title>The Factory Pattern, Explained in Ruby</title><link>https://jakeworth.com/posts/why-use-factorybot/</link><pubDate>Mon, 17 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/why-use-factorybot/</guid><description>&lt;p&gt;In this post, I&amp;rsquo;ll explain what factories are and why you want them, using Ruby.&lt;/p&gt;</description></item><item><title>Default to Programming Convention</title><link>https://jakeworth.com/posts/default-to-convention/</link><pubDate>Fri, 14 Oct 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/default-to-convention/</guid><description>&lt;p&gt;Trying to enforce unconventional coding preferences on a team is an uphill
battle. When in doubt, default to convention.&lt;/p&gt;</description></item><item><title>Recommended Reading</title><link>https://jakeworth.com/posts/recommended-reading/</link><pubDate>Wed, 28 Sep 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/recommended-reading/</guid><description>&lt;p&gt;Here are some books that have helped me understand programming. This list is a
living document that I plan to update as I read.&lt;/p&gt;</description></item><item><title>How to Introduce New Ideas</title><link>https://jakeworth.com/posts/how-to-introduce-new-ideas/</link><pubDate>Thu, 08 Sep 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-to-introduce-new-ideas/</guid><description>&lt;p&gt;How do you introduce new ways of working? We want to bring a new idea
to our engineering teams, such as a new command-line configuration, testing
tool, or design pattern. But engineers can be discerning and stubborn customers.
The idea needs to stand on its own. And, you have to sell it.&lt;/p&gt;</description></item><item><title>Computers Can Be Understood</title><link>https://jakeworth.com/posts/computers-can-be-understood/</link><pubDate>Tue, 06 Sep 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/computers-can-be-understood/</guid><description>&lt;p&gt;A big mental leap I made early in my programming was starting to view computers
as something that could be understood.&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>Vim Scratchpad</title><link>https://jakeworth.com/posts/vim-scratchpad/</link><pubDate>Thu, 25 Aug 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/vim-scratchpad/</guid><description>&lt;p&gt;Today I&amp;rsquo;d like to share a small part of my practice: using a persisted
scratchpad text file for jotting things down.&lt;/p&gt;</description></item><item><title>Improve Your API Documentation Workflow with Dash</title><link>https://jakeworth.com/posts/level-up-your-dash/</link><pubDate>Sun, 21 Aug 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/level-up-your-dash/</guid><description>&lt;p&gt;One of my all-time favorite programming tools is Dash by Kapeli. In this post,
I&amp;rsquo;ll share some tips for leveraging this fantastic program.&lt;/p&gt;</description></item><item><title>Prefer Real Data For Software Development</title><link>https://jakeworth.com/posts/prefer-real-data/</link><pubDate>Thu, 18 Aug 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/prefer-real-data/</guid><description>&lt;p&gt;When testing with data, I prefer realistic data rather than random data.&lt;/p&gt;</description></item><item><title>How Luck Played a Role in my Career</title><link>https://jakeworth.com/posts/luck-played-a-role/</link><pubDate>Mon, 15 Aug 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/luck-played-a-role/</guid><description>&lt;p&gt;I believe that luck is part of every professional journey. Here&amp;rsquo;s a sampling of
the luck I&amp;rsquo;ve had.&lt;/p&gt;</description></item><item><title>All My Best Debugging Tips</title><link>https://jakeworth.com/posts/all-my-best-debugging-tips/</link><pubDate>Fri, 05 Aug 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/all-my-best-debugging-tips/</guid><description>&lt;p&gt;This is a list of all the best debugging tips I&amp;rsquo;ve picked up over the years. Some of these might seem obvious, yet we forget them when it
counts. Debugging is a skill. You have to bring every tool you have to the job.&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>Tmux Application Startup Script</title><link>https://jakeworth.com/posts/tmux-application-startup-script/</link><pubDate>Thu, 28 Jul 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/tmux-application-startup-script/</guid><description>&lt;p&gt;My development environment depends on several processes running. Here&amp;rsquo;s how
I&amp;rsquo;ve scripted this setup.&lt;/p&gt;</description></item><item><title>Recognizing and Repairing a Broken Mental Model</title><link>https://jakeworth.com/posts/broken-mental-model/</link><pubDate>Mon, 25 Jul 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/broken-mental-model/</guid><description>&lt;p&gt;Perhaps you&amp;rsquo;re familiar with this scenario: you&amp;rsquo;re debugging and
&lt;a href="https://jakeworth.com/posts/dont-stay-stuck/"&gt;stuck&lt;/a&gt;. You&amp;rsquo;ve Googled, read some blog posts and docs.
You return to your search engine, type some characters, and then something
strange happens: the search engine autocompletes your question, and the results
are all purple because they have been visited by you. I&amp;rsquo;ve come to recognize
this moment as always a symptom of a broken mental model.&lt;/p&gt;</description></item><item><title>Retros Need Action Items</title><link>https://jakeworth.com/posts/retros-need-action-items/</link><pubDate>Tue, 19 Jul 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/retros-need-action-items/</guid><description>&lt;p&gt;Action items are small, defined, actionable TODOs to follow up on after the
meeting. An example: &amp;ldquo;close all pull requests opened more than 90 days ago.&amp;rdquo;
Agile retrospectives should produce many of these.&lt;/p&gt;</description></item><item><title>Better Than 'foo'</title><link>https://jakeworth.com/posts/better-than-foo/</link><pubDate>Wed, 13 Jul 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/better-than-foo/</guid><description>&lt;p&gt;There&amp;rsquo;s almost always a better variable name or value than &amp;lsquo;foo&amp;rsquo;. It&amp;rsquo;s useful
as a debugging placeholder, but it almost never belongs in production code, even and
especially in automated tests.&lt;/p&gt;</description></item><item><title>Database Migration Checklist</title><link>https://jakeworth.com/posts/database-migration-checklist/</link><pubDate>Mon, 11 Jul 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/database-migration-checklist/</guid><description>&lt;p&gt;I think a great database migration is: correct, atomic, reversible,
consistent with the style of the application, and (mostly) uncoupled from your
application and RDBMS.&lt;/p&gt;</description></item><item><title>Logging an Object in JavaScript</title><link>https://jakeworth.com/posts/logging-an-object/</link><pubDate>Thu, 07 Jul 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/logging-an-object/</guid><description>&lt;p&gt;When printing a JavaScript value to the console, I suggest using an object
literal over the raw value.&lt;/p&gt;</description></item><item><title>Why Ruby?</title><link>https://jakeworth.com/posts/why-ruby/</link><pubDate>Thu, 30 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/why-ruby/</guid><description>&lt;p&gt;Why should someone learn Ruby in 2022? Ruby was my first programming language, and although I&amp;rsquo;ve drifted elsewhere, I
write Ruby every day. Many people in my network are Ruby diehards. As a result,
it&amp;rsquo;s been a long time since I&amp;rsquo;ve gotten the chance to sell someone on Ruby.&lt;/p&gt;</description></item><item><title>What Are the Tradeoffs of Passing Objects as React Props?</title><link>https://jakeworth.com/posts/objects-as-props/</link><pubDate>Mon, 27 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/objects-as-props/</guid><description>&lt;p&gt;A common React pattern is to pass an object as a &lt;a href="https://reactjs.org/docs/components-and-props.html"&gt;prop&lt;/a&gt;. Let&amp;rsquo;s consider the ways this can be used and tradeoffs of each.&lt;/p&gt;</description></item><item><title>Naive Implementation: The Art of Artless Programming</title><link>https://jakeworth.com/posts/naive-implementation/</link><pubDate>Thu, 23 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/naive-implementation/</guid><description>&lt;p&gt;A naive implementation is a programming technique that prioritizes imperfect
shortcuts for the sake of speed, simplicity, or lack of knowledge.&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>Authentication vs. Authorization</title><link>https://jakeworth.com/posts/authentication-vs-authorization/</link><pubDate>Tue, 21 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/authentication-vs-authorization/</guid><description>&lt;p&gt;Authentication and authorization are two distinct concepts. Yet, I&amp;rsquo;ve found
they&amp;rsquo;re sometimes used interchangeably. In this post, I&amp;rsquo;d like to define these terms.&lt;/p&gt;</description></item><item><title>Spell Checking with Vim: Tutorial and Best Practices</title><link>https://jakeworth.com/posts/spell-check-with-vim/</link><pubDate>Wed, 15 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/spell-check-with-vim/</guid><description>&lt;p&gt;I write each post for this blog in Vim. Writing in the terminal makes me feel
like a programmer, even when I&amp;rsquo;m not specifically programming. In this post, I&amp;rsquo;ll share how I spellcheck in Vim.&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>How to Write a Perfect Bug Report (With Template)</title><link>https://jakeworth.com/posts/a-perfect-bug-report/</link><pubDate>Mon, 13 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/a-perfect-bug-report/</guid><description>&lt;p&gt;Bugs are part of software. Reporting bugs well is a necessary skill in an ever-growing number of job titles. In this post, I&amp;rsquo;d like to explain how to write a perfect bug report and offer some bug-reporting best practices.&lt;/p&gt;</description></item><item><title>Make a Prediction</title><link>https://jakeworth.com/posts/make-a-prediction/</link><pubDate>Wed, 08 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/make-a-prediction/</guid><description>&lt;p&gt;Imagine you&amp;rsquo;re debugging, and you&amp;rsquo;re &lt;a href="https://jakeworth.com/posts/dont-stay-stuck/"&gt;stuck&lt;/a&gt;. I have a technique that&amp;rsquo;s
going to help. Think of an action you might take. Predict what will happen
when you take that action. Take the action. Check if you were right or wrong,
consider that information, and repeat.&lt;/p&gt;</description></item><item><title>Desire Paths in Software</title><link>https://jakeworth.com/posts/desire-paths/</link><pubDate>Sun, 05 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/desire-paths/</guid><description>&lt;p&gt;We&amp;rsquo;ve all seen a &lt;a href="https://en.wikipedia.org/wiki/Desire_path"&gt;desire path&lt;/a&gt;. They are footpaths created by erosion from
human and animal traffic that communicate a wish for a path that doesn&amp;rsquo;t exist.
When you walk on a paved path toward a destination and notice a shortcut in
the earth, that&amp;rsquo;s a desire path. It&amp;rsquo;s the way people go, rather than the way we
would wish them to go.&lt;/p&gt;</description></item><item><title>Spend More Time Thinking Hard</title><link>https://jakeworth.com/posts/think-hard/</link><pubDate>Wed, 01 Jun 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/think-hard/</guid><description>&lt;p&gt;Ben Kuhn&amp;rsquo;s &lt;a href="https://www.benkuhn.net/thinkrealhard/"&gt;&amp;lsquo;Think Real Hard&amp;rsquo;&lt;/a&gt; shares a problem-solving checklist from the scientist Richard Feynman:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Write down the problem.&lt;/li&gt;
&lt;li&gt;Think real hard.&lt;/li&gt;
&lt;li&gt;Write down the solution.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;On its face, this advice is ridiculous. If only we just sat and thought about
the problem, we&amp;rsquo;d win a Nobel Prize like Dr. Feynman!&lt;/p&gt;</description></item><item><title>PostgreSQL Polymorphism</title><link>https://jakeworth.com/posts/postgresql-polymorphism/</link><pubDate>Mon, 30 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/postgresql-polymorphism/</guid><description>&lt;p&gt;Scenario: you need a database record that can belong to one record or another, but not
both. Polymorphism and exclusivity. One approach is to create a polymorphic-style association at
the data layer. By doing so, you&amp;rsquo;ll get data integrity built in, rather than
trusting it will be enforced by each tenant at the application layer.&lt;/p&gt;</description></item><item><title>Goodbye Shared Dotfiles</title><link>https://jakeworth.com/posts/goodbye-shared-dotfiles/</link><pubDate>Wed, 25 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/goodbye-shared-dotfiles/</guid><description>&lt;p&gt;A lot of people start programming with shared dotfiles, copied from a team or
online. I did. Maybe you&amp;rsquo;re ready to move on; how would you do that?&lt;/p&gt;</description></item><item><title>Organizing React Components</title><link>https://jakeworth.com/posts/organizing-react-components/</link><pubDate>Mon, 23 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/organizing-react-components/</guid><description>&lt;p&gt;You&amp;rsquo;re creating a React app, and want to organize your components. Or maybe
you&amp;rsquo;re working in a legacy codebase, with many components in one directory, and
you want to better organize them. In this post, I&amp;rsquo;ll document an approach to
this problem that has worked for me.&lt;/p&gt;</description></item><item><title>On Starting Over</title><link>https://jakeworth.com/posts/on-starting-over/</link><pubDate>Wed, 18 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/on-starting-over/</guid><description>&lt;p&gt;I used to have a bad habit when working alone: I&amp;rsquo;d start a feature, begin
doubting my approach, throw away my work, and start over from scratch.
Sometimes more than once. The result? Wasted energy, abandoned code, confusion
about what I had and hadn&amp;rsquo;t implemented, and repetitive rework. This post is a
collection of thoughts on this practice.&lt;/p&gt;</description></item><item><title>How to Identify the Breaking Commit With Git Bisect</title><link>https://jakeworth.com/posts/find-the-breaking-git-commit/</link><pubDate>Tue, 17 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/find-the-breaking-git-commit/</guid><description>&lt;p&gt;Some code is broken, and you can&amp;rsquo;t figure out why. Maybe there are a lot of changes, and identifying the breaking change seems impossible. Or, maybe you&amp;rsquo;re curious about how things break in your organization. The tool you need is &lt;code&gt;git-bisect&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>Commit Part of a File in Git</title><link>https://jakeworth.com/posts/commit-part-of-a-file-in-git/</link><pubDate>Fri, 06 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/commit-part-of-a-file-in-git/</guid><description>&lt;p&gt;You&amp;rsquo;ve been working on a big set of changes, and haven&amp;rsquo;t committed to Git yet.
Now, you want to commit some, but not all, changes to a file. Let&amp;rsquo;s look
at adding patches.&lt;/p&gt;</description></item><item><title>You Have to Get Fast to Get Good at Programming</title><link>https://jakeworth.com/posts/be-fast/</link><pubDate>Fri, 06 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/be-fast/</guid><description>&lt;p&gt;Great programmers aren&amp;rsquo;t fast because they&amp;rsquo;re great. They&amp;rsquo;re great because they&amp;rsquo;re fast.&lt;/p&gt;</description></item><item><title>Only One Way Out of a Function</title><link>https://jakeworth.com/posts/one-way-out-of-a-function/</link><pubDate>Mon, 02 May 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/one-way-out-of-a-function/</guid><description>&lt;p&gt;A programming style I try to practice could be described as: &amp;ldquo;there should be
only one way out of a function.&amp;rdquo; Early returns can often cause more confusion
than they&amp;rsquo;re worth. When possible, I avoid them in favor of a single return.&lt;/p&gt;</description></item><item><title>Am I Too Old to Become a Programmer?</title><link>https://jakeworth.com/posts/am-i-too-old-to-become-a-programmer/</link><pubDate>Thu, 28 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/am-i-too-old-to-become-a-programmer/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&amp;ldquo;The best time to plant a tree was twenty years ago. The second best time is
now.&amp;rdquo;
&amp;ndash; Chinese proverb&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I mentor adults who are learning to program after serving in the military.
Some are in their late twenties, and some are twice that age. A common concern
is that they are too old to be changing careers to programming.&lt;/p&gt;</description></item><item><title>It's Harder to Read Code Than Write It</title><link>https://jakeworth.com/posts/its-harder-to-read-code-than-write-it/</link><pubDate>Mon, 25 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/its-harder-to-read-code-than-write-it/</guid><description>&lt;p&gt;In &lt;a href="https://www.joelonsoftware.com/2000/04/06/things-you-should-never-do-part-i/"&gt;Things You Should Never Do, Part I&lt;/a&gt;, Joel Spolsky narrates
Netscape&amp;rsquo;s ruinous decision to rewrite their browser from scratch. This
introduced the following concept to me: &amp;ldquo;It&amp;rsquo;s harder to read code than to write it.&amp;rdquo; I believe this is true. Today I&amp;rsquo;d like to explain why.&lt;/p&gt;</description></item><item><title>The Problems With Code Screenshots</title><link>https://jakeworth.com/posts/on-code-screenshots/</link><pubDate>Tue, 19 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/on-code-screenshots/</guid><description>&lt;p&gt;Screenshots of code are common in developer communication, but they come with real drawbacks. Here&amp;rsquo;s why I try to avoid them.&lt;/p&gt;</description></item><item><title>Hash Fetch Instead of If/Else</title><link>https://jakeworth.com/posts/hash-fetch-instead-of-if-else/</link><pubDate>Sat, 16 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/hash-fetch-instead-of-if-else/</guid><description>&lt;p&gt;Conditional logic has its place, but often there&amp;rsquo;s a better alternative.
Today, we&amp;rsquo;ll look at a Ruby solution: a hash with &lt;code&gt;.fetch&lt;/code&gt;.&lt;/p&gt;</description></item><item><title>First Get It Working, Then Make it Look Good</title><link>https://jakeworth.com/posts/get-it-working-first/</link><pubDate>Wed, 13 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/get-it-working-first/</guid><description>&lt;p&gt;I recently completed a winter survival course where we built shelters in just
ten minutes with only the contents of our packs. The pack I brought was nearly
empty, so I made a tent out of my parka. It was ugly, but it could have saved
my life. How does this apply to software? When building a feature, first get it
working, then make it look good.&lt;/p&gt;</description></item><item><title>My psql Config</title><link>https://jakeworth.com/posts/my-psql-config/</link><pubDate>Tue, 12 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/my-psql-config/</guid><description>&lt;p&gt;RC files, thought to stand for &amp;ldquo;run command&amp;rdquo; files, are read by a program
during startup. The file that configures the PostgreSQL REPL psql is called
&lt;code&gt;.psqlrc&lt;/code&gt;. In this post I&amp;rsquo;ll share my personal psql configuration.&lt;/p&gt;</description></item><item><title>Solved! How to Exit Vim "Ex" Mode</title><link>https://jakeworth.com/posts/exit-vim-ex-mode/</link><pubDate>Wed, 06 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/exit-vim-ex-mode/</guid><description>&lt;p&gt;How does one exit Vim &amp;ldquo;Ex&amp;rdquo; mode? But first&amp;hellip; how did you even get into &amp;ldquo;Ex&amp;rdquo; mode?&lt;/p&gt;</description></item><item><title>How to Read a Stack Trace</title><link>https://jakeworth.com/posts/how-to-read-a-stack-trace/</link><pubDate>Tue, 05 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-to-read-a-stack-trace/</guid><description>&lt;p&gt;A stumbling block for many people when debugging is reading the stack trace.
Today I&amp;rsquo;d like to discuss this important skill.&lt;/p&gt;</description></item><item><title>RSpec.describe vs. describe: Which Should I Use?</title><link>https://jakeworth.com/posts/rspec-describe-vs-describe/</link><pubDate>Sat, 02 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/rspec-describe-vs-describe/</guid><description>&lt;p&gt;Ruby&amp;rsquo;s RSpec &lt;code&gt;describe&lt;/code&gt; block has two common syntaxes. Which should you use?&lt;/p&gt;</description></item><item><title>Your Demo Doesn't Need Auth</title><link>https://jakeworth.com/posts/your-demo-doesnt-need-auth/</link><pubDate>Fri, 01 Apr 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/your-demo-doesnt-need-auth/</guid><description>&lt;p&gt;When building a demo application, I believe you can often skip authentication.&lt;/p&gt;</description></item><item><title>How Urgent Is This Bug?</title><link>https://jakeworth.com/posts/the-importance-of-a-bug/</link><pubDate>Wed, 30 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/the-importance-of-a-bug/</guid><description>&lt;p&gt;I remember the first bug that I shipped to production. I was upset that I&amp;rsquo;d
broken something and was anxious to fix it. But I noticed something curious:
the calm demeanor of a senior mentor helping me. They refused to meet my intensity. While the world burned, they wanted to instead discuss the bug and its relative importance.&lt;/p&gt;</description></item><item><title>Debugging Tip: Learning From Bugs</title><link>https://jakeworth.com/posts/learn-from-it/</link><pubDate>Fri, 25 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/learn-from-it/</guid><description>&lt;p&gt;You were &lt;a href="https://jakeworth.com/posts/dont-stay-stuck/"&gt;stuck&lt;/a&gt;, and now you aren&amp;rsquo;t. Congratulations! Before you move
on, it&amp;rsquo;s vital to stop and learn from it. It&amp;rsquo;s the best way I know to get
better and spare your mind for increasingly harder problems.&lt;/p&gt;</description></item><item><title>How to Make Renames Easy</title><link>https://jakeworth.com/posts/make-renames-easy/</link><pubDate>Tue, 22 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/make-renames-easy/</guid><description>&lt;p&gt;Names in software are hard. But what&amp;rsquo;s worse than a bad name? Sticking with it
because you can&amp;rsquo;t change it. I want us all to be able to effortlessly and
fearlessly fix bad names. That&amp;rsquo;s the topic of this post.&lt;/p&gt;</description></item><item><title>How to Read Postgres Docs</title><link>https://jakeworth.com/posts/how-to-read-postgres-docs/</link><pubDate>Mon, 21 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-to-read-postgres-docs/</guid><description>&lt;p&gt;Have you ever tried to read the documentation for a Postgres command? Although
many consider Postgres&amp;rsquo; docs best-in-class, they include conventions that might
challenge newbies. In this post, I&amp;rsquo;ll paraphrase Postgres&amp;rsquo; conventions page to
help us understand what the documentation for a command is saying.&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>Stop Studying, Start Building</title><link>https://jakeworth.com/posts/build/</link><pubDate>Wed, 16 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/build/</guid><description>&lt;p&gt;If I could give one piece of advice to anyone learning to program: build.&lt;/p&gt;</description></item><item><title>Which Operating System Is the Best for Programming?</title><link>https://jakeworth.com/posts/try-every-os/</link><pubDate>Mon, 14 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/try-every-os/</guid><description>&lt;p&gt;Which operating system is the best for programming? This is a perennial
question in code boot camps where I&amp;rsquo;ve taught. I think students see the choice
as a fork in the road, and they want pick the right direction. I don&amp;rsquo;t think
there is a right direction. When you&amp;rsquo;re starting out, my advice is to try each
one and choose for yourself.&lt;/p&gt;</description></item><item><title>Autoformat Your Code</title><link>https://jakeworth.com/posts/autoformat-your-code/</link><pubDate>Thu, 10 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/autoformat-your-code/</guid><description>&lt;p&gt;Auto-formatting code is good, and you should be doing it all the time. Why? It
helps you write better code in real-time, preempt trivial discussions, and maybe even democratize programming.&lt;/p&gt;</description></item><item><title>How I Review Code</title><link>https://jakeworth.com/posts/how-i-review-code/</link><pubDate>Sun, 06 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-i-review-code/</guid><description>&lt;p&gt;Code reviews are important on many teams. Do them well, and your code ships
quickly and safely. Do them poorly, and your code ships slowly and riskily. I
try to contribute good code reviews. In this post, I&amp;rsquo;ll share my process.&lt;/p&gt;</description></item><item><title>How I Make Sure I Understand a Feature Before Building</title><link>https://jakeworth.com/posts/how-i-make-sure-i-understand-a-feature-before-building/</link><pubDate>Wed, 02 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-i-make-sure-i-understand-a-feature-before-building/</guid><description>&lt;p&gt;I think the most important factor in consistent delivery is understanding the
work. When you understand the work, you build what the stakeholder wants,
better and faster.&lt;/p&gt;</description></item><item><title>Don't Stay Stuck</title><link>https://jakeworth.com/posts/dont-stay-stuck/</link><pubDate>Tue, 01 Mar 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/dont-stay-stuck/</guid><description>&lt;p&gt;We&amp;rsquo;ve all seen this: a frustrated coworker hunched over a computer after
hours, flailing alone against some impossible bug. Go home, coworker. Don&amp;rsquo;t stay stuck.&lt;/p&gt;</description></item><item><title>Why Vim</title><link>https://jakeworth.com/posts/why-vim/</link><pubDate>Wed, 23 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/why-vim/</guid><description>&lt;p&gt;I&amp;rsquo;ve been using, teaching, and stanning &lt;a href="https://www.vim.org/"&gt;Vim&lt;/a&gt; since almost the beginning of my
programming career. Yet, when asked to explain this preference, I stumble. In
this post, I&amp;rsquo;d like to explore why I love Vim.&lt;/p&gt;</description></item><item><title>On Disabling Tests</title><link>https://jakeworth.com/posts/on-disabling-tests/</link><pubDate>Tue, 22 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/on-disabling-tests/</guid><description>&lt;p&gt;Today I want to talk about a common technique: disabling failing tests to allow
a feature to ship. Maybe sometimes you gotta do it. But long-term I think it
causes more problems than it solves.&lt;/p&gt;</description></item><item><title>Before You Abort, Count to Ten</title><link>https://jakeworth.com/posts/count-to-ten/</link><pubDate>Tue, 15 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/count-to-ten/</guid><description>&lt;p&gt;Here&amp;rsquo;s a trick that that has helped me as a programmer: before doing anything
major, like killing a process, stop and count to ten.&lt;/p&gt;</description></item><item><title>Avoid Similar Variable Names</title><link>https://jakeworth.com/posts/avoid-similar-variable-names/</link><pubDate>Mon, 14 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/avoid-similar-variable-names/</guid><description>&lt;p&gt;A common, problematic convention I see in Ruby tests are variable names 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;user_a &lt;span style="color:#f92672"&gt;=&lt;/span&gt; create(&lt;span style="color:#e6db74"&gt;:user&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;last_log_in&lt;/span&gt;: today)
&lt;/span&gt;&lt;/span&gt;&lt;span style="display:flex;"&gt;&lt;span&gt;user_b &lt;span style="color:#f92672"&gt;=&lt;/span&gt; create(&lt;span style="color:#e6db74"&gt;:user&lt;/span&gt;, &lt;span style="color:#e6db74"&gt;last_log_in&lt;/span&gt;: last_year)
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</description></item><item><title>Refining Your Terminal Aliases</title><link>https://jakeworth.com/posts/alias-terminal-commands/</link><pubDate>Thu, 10 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/alias-terminal-commands/</guid><description>&lt;p&gt;Any command you type out manually, or even tab-complete a few times, can be
shortened. A common shortening technique is the terminal alias. Here are some tips that help me write better aliases and cut my terminal keystrokes.&lt;/p&gt;</description></item><item><title>Ruby's Frozen String Literal Comment: YAGNI</title><link>https://jakeworth.com/posts/frozen-string-comment-yagni/</link><pubDate>Wed, 09 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/frozen-string-comment-yagni/</guid><description>&lt;p&gt;Open a production Ruby file, and you&amp;rsquo;ll often see this magic comment at the
top.&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;# frozen_string_literal: true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Today I&amp;rsquo;d like to argue that most Ruby files do not need this comment. YAGNI— You
Aren&amp;rsquo;t Going to Need It.&lt;/p&gt;</description></item><item><title>Why I Don't Point Agile Bug Tickets</title><link>https://jakeworth.com/posts/why-i-dont-point-bugs/</link><pubDate>Mon, 07 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/why-i-dont-point-bugs/</guid><description>&lt;p&gt;When I create Agile bug tickets, I leave the story points blank. Why? Two reasons: pointing bugs creates the wrong incentives, and bugs are hard to estimate.&lt;/p&gt;</description></item><item><title>Weekly Summary Technique for Software Engineers</title><link>https://jakeworth.com/posts/weekly-summary-routine/</link><pubDate>Fri, 04 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/weekly-summary-routine/</guid><description>&lt;p&gt;&lt;em&gt;&amp;ldquo;What did you do this week?&amp;rdquo;&lt;/em&gt; I&amp;rsquo;ve written a weekly summary for myself and my
teams for years. It helps me think through my work and shows people what I&amp;rsquo;m
working on. In this post, I&amp;rsquo;ll explain how to use this tool.&lt;/p&gt;</description></item><item><title>Opt Into Beta</title><link>https://jakeworth.com/posts/opt-into-beta/</link><pubDate>Wed, 02 Feb 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/opt-into-beta/</guid><description>&lt;p&gt;Here&amp;rsquo;s a technique I&amp;rsquo;ve used on launches: instead of a big scary waterfall, or,
in tandem with a phased release, let customers opt into a new feature.&lt;/p&gt;</description></item><item><title>How to Find a Programming Mentor</title><link>https://jakeworth.com/posts/finding-a-mentor/</link><pubDate>Mon, 31 Jan 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/finding-a-mentor/</guid><description>&lt;p&gt;I have collected a group of mentors over the years. I call on
them frequently to talk through tough problems. I think I&amp;rsquo;m better at my job because of
this regular, impartial outside feedback. I&amp;rsquo;d wish this for everyone! In this post, I&amp;rsquo;ll try to
reverse-engineer the path I took to get here.&lt;/p&gt;</description></item><item><title>Use a Dev Email</title><link>https://jakeworth.com/posts/use-a-dev-email/</link><pubDate>Sat, 29 Jan 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/use-a-dev-email/</guid><description>&lt;p&gt;An engineering technique I recommend: when you sign up for any service, even on
a side project that&amp;rsquo;s just getting off the ground, create an email group called
&lt;code&gt;dev@&amp;lt;your-domain.com&amp;gt;&lt;/code&gt; that forwards to you and any other technologists, and
use that email to sign up.&lt;/p&gt;</description></item><item><title>How to Answer Questions on Stack Overflow</title><link>https://jakeworth.com/posts/answering-questions-on-stack-overflow/</link><pubDate>Thu, 27 Jan 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/answering-questions-on-stack-overflow/</guid><description>&lt;p&gt;Here&amp;rsquo;s my simple framework for answering questions on Stack Overflow that reach and help people and earn reputation.&lt;/p&gt;</description></item><item><title>Want Better Automated Tests? Hard-Code Your Expectations</title><link>https://jakeworth.com/posts/hard-code-your-expectations/</link><pubDate>Tue, 25 Jan 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/hard-code-your-expectations/</guid><description>&lt;p&gt;Hard-coded test expectations have many benefits that I&amp;rsquo;ll explore in this post.&lt;/p&gt;</description></item><item><title>Presence is Boolean</title><link>https://jakeworth.com/posts/presence-is-boolean/</link><pubDate>Mon, 24 Jan 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/presence-is-boolean/</guid><description>&lt;p&gt;When possible, I prefer to use the &lt;em&gt;presence of data&lt;/em&gt; to &lt;em&gt;represent&lt;/em&gt; a boolean, rather than a
boolean itself.&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>Be a Better Technical Consultant by Saying "I Think That..."</title><link>https://jakeworth.com/posts/i-think-that/</link><pubDate>Wed, 19 Jan 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/i-think-that/</guid><description>&lt;p&gt;An idea I find useful as an individual contributor is starting my consulting
with this phrase: &amp;ldquo;I think that&amp;hellip;&amp;rdquo;. The idea is to let your arguments stand on
their own, rather than appealing to your experience or other authorities.&lt;/p&gt;</description></item><item><title>Bug Reports Are Gold</title><link>https://jakeworth.com/posts/bug-reports-are-gold/</link><pubDate>Sat, 15 Jan 2022 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/bug-reports-are-gold/</guid><description>&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;Me&lt;/strong&gt;: Hey, I&amp;rsquo;m experiencing an issue with your software. Here&amp;rsquo;s a &lt;a href="https://jakeworth.com/posts/a-perfect-bug-report/"&gt;detailed bug report&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;SAAS Engineer&lt;/strong&gt;: What you&amp;rsquo;re describing isn&amp;rsquo;t possible.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Narrator:&lt;/strong&gt; &lt;em&gt;But it was possible.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;This is a frustrating, unproductive snippet of a conversation I&amp;rsquo;ve had a few times in my
career. What can we learn? Treat bug reports like gold.&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>Why Getting Good Solves Most Career Problems</title><link>https://jakeworth.com/posts/get-good/</link><pubDate>Wed, 13 Oct 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/get-good/</guid><description>&lt;p&gt;What should you focus on at the beginning of your programming career? My unflashy answer is: being really good at programming.&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>How to Organize JavaScript Imports</title><link>https://jakeworth.com/posts/javascript-import-opinions/</link><pubDate>Mon, 30 Aug 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/javascript-import-opinions/</guid><description>&lt;p&gt;The &lt;code&gt;import&lt;/code&gt; statements at the top of a JavaScript component file can be a
confusing, duplicative, churning mess. Is there a way to organize them that
makes sense and scales? In this post, I&amp;rsquo;d like to share the way I handle this detail.&lt;/p&gt;</description></item><item><title>Write Better Code by Knowing When Not To Refactor</title><link>https://jakeworth.com/posts/when-should-i-not-refactor/</link><pubDate>Thu, 26 Aug 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/when-should-i-not-refactor/</guid><description>&lt;p&gt;When I review code, I sometimes request that refactoring changes be removed.
Even when I think the changes are are objective improvements, and even when
they support my personal preferences. My reasoning? Refactors are not free.&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>The Tutorial Anti-Pattern</title><link>https://jakeworth.com/posts/the-tutorial-antipattern/</link><pubDate>Tue, 24 Aug 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/the-tutorial-antipattern/</guid><description>&lt;p&gt;Here&amp;rsquo;s a scenario: you&amp;rsquo;re applying for your first tech job. You&amp;rsquo;ve found a
bunch of hands-on tutorials and you&amp;rsquo;re speeding through them. When
you finish, you upload the code to Github and add a new line to the &amp;lsquo;Projects&amp;rsquo;
section of your resume. Maybe you even deploy the code as a production website.
My advice: stop.&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>Consultancy Cycles</title><link>https://jakeworth.com/posts/consultancy-cycles/</link><pubDate>Wed, 04 Aug 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/consultancy-cycles/</guid><description>&lt;p&gt;Working at a quality software development consultancy like
&lt;a href="https://hashrocket.com/"&gt;Hashrocket&lt;/a&gt; early in your programming career could be a
game-changing move.&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>What is the Sub Claim of a JSON Web Token?</title><link>https://jakeworth.com/posts/til-what-is-the-jwt-sub/</link><pubDate>Fri, 02 Apr 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/til-what-is-the-jwt-sub/</guid><description>&lt;p&gt;Today I&amp;rsquo;d like to explain the &lt;code&gt;sub&lt;/code&gt;, or subject, registered claim of a &lt;a href="https://jwt.io/"&gt;JSON Web
Token&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>Augmenting an Object With the Proxy Pattern</title><link>https://jakeworth.com/posts/proxy-pattern/</link><pubDate>Fri, 26 Feb 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/proxy-pattern/</guid><description>&lt;p&gt;Let&amp;rsquo;s look at the proxy pattern in Ruby.&lt;/p&gt;</description></item><item><title>Do the Hard Things First</title><link>https://jakeworth.com/posts/do-the-hard-things-first/</link><pubDate>Mon, 25 Jan 2021 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/do-the-hard-things-first/</guid><description>&lt;p&gt;A concept that I admire is &amp;lsquo;Doing the Hard Thing First&amp;rsquo; via
Ben Orenstein. Ben described on the &lt;a href="https://artofproductpodcast.com/episode-50"&gt;Art of Product Podcast Episode
50&lt;/a&gt;. Here&amp;rsquo;s my summary:&lt;/p&gt;
&lt;p&gt;Choose the hard part of the problem, the part you’re unsure about, the part
that success depends on, and solve that first!&lt;/p&gt;</description></item><item><title>Exercism Raindrops in Python</title><link>https://jakeworth.com/posts/exercism-raindrops-in-python/</link><pubDate>Sun, 06 Dec 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/exercism-raindrops-in-python/</guid><description>&lt;p&gt;I&amp;rsquo;ve been learning a bit of Python this Fall to facilitate conversations with a
mentee. In this post, I&amp;rsquo;m going to share the first Python function I&amp;rsquo;ve ever
written, a solution to the &lt;a href="https://exercism.io"&gt;Exercism&lt;/a&gt; challenge
&amp;lsquo;Raindrops&amp;rsquo;.&lt;/p&gt;</description></item><item><title>Programming Resources for Beginners</title><link>https://jakeworth.com/posts/programming-resources-for-beginners/</link><pubDate>Sat, 05 Dec 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/programming-resources-for-beginners/</guid><description>&lt;p&gt;There is a glut of programming information
online. You can&amp;rsquo;t read it all, and you shouldn&amp;rsquo;t, because much of it is
outdated, wrong, or irrelevant to you.&lt;/p&gt;
&lt;p&gt;So, what is the signal in this noise? I recommend aggregators, blogs, pair
programming. And I offer a gentle recommendation against tutorials.&lt;/p&gt;</description></item><item><title>My Annotated Vim Configuration File</title><link>https://jakeworth.com/posts/my-annotated-vimrc/</link><pubDate>Thu, 26 Nov 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/my-annotated-vimrc/</guid><description>&lt;p&gt;I love Vim. Folks who&amp;rsquo;ve programmed with me, or attended a Vim Meetup when I
was an organizer, can attest. When I was learning to code, &lt;a href="https://jakeworth.com/posts/be-fast/"&gt;getting
fast&lt;/a&gt; at Vim changed everything for me. After almost a decade using this editor, here are my personal configurations.&lt;/p&gt;</description></item><item><title>Essays on Programming I Think About a Lot</title><link>https://jakeworth.com/posts/essays-on-programming-i-think-about-a-lot/</link><pubDate>Thu, 29 Oct 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/essays-on-programming-i-think-about-a-lot/</guid><description>&lt;p&gt;Programming is a new and abstract field, and so we place great emphasis on
ideas. When I find one that sticks with me, I end up sharing it again and again. These
are some of my favorites.&lt;/p&gt;</description></item><item><title>My Development Roadmap</title><link>https://jakeworth.com/posts/my-development-roadmap/</link><pubDate>Tue, 20 Oct 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/my-development-roadmap/</guid><description>&lt;p&gt;I&amp;rsquo;ve been working on a development roadmap for my projects, and wanted to share
my process. Consider this my recipe to turn an idea into software.&lt;/p&gt;</description></item><item><title>You Have New Mail</title><link>https://jakeworth.com/posts/you-have-new-mail/</link><pubDate>Fri, 16 Oct 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/you-have-new-mail/</guid><description>&lt;p&gt;Here&amp;rsquo;s a familiar scenario: you open a new terminal, and before the prompt
appears, you see the following.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;You have new mail.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;What&amp;rsquo;s going on here?&lt;/p&gt;</description></item><item><title>Duplicate your Development Branch for QA</title><link>https://jakeworth.com/posts/duplicate-your-developent-branch-for-qa/</link><pubDate>Fri, 09 Oct 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/duplicate-your-developent-branch-for-qa/</guid><description>&lt;p&gt;I&amp;rsquo;m working on a team where we keep a clone of the &lt;code&gt;development&lt;/code&gt; branch (the main
place where work is done), used to deploy to a QA environment. The benefits of
this branching technique are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;clone&lt;/code&gt; is isolated from work&lt;/li&gt;
&lt;li&gt;It&amp;rsquo;s easy to tell what was deployed to QA– &lt;code&gt;clone&lt;/code&gt; is the source of truth&lt;/li&gt;
&lt;/ul&gt;</description></item><item><title>How I Clean Up JavaScript Dependencies</title><link>https://jakeworth.com/posts/how-i-clean-up-unused-javascript-dependencies/</link><pubDate>Mon, 03 Aug 2020 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-i-clean-up-unused-javascript-dependencies/</guid><description>&lt;p&gt;Unused dependencies are bad: they increase the size of your project, slow down
your processes, require upgrades, and send incorrect messages to fellow
developers about what&amp;rsquo;s important. Make your project better by periodically auditing your dependencies, and
removing those that are unused.&lt;/p&gt;</description></item><item><title>My Annual Review 2019</title><link>https://jakeworth.com/posts/my-annual-review-2019/</link><pubDate>Tue, 31 Dec 2019 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/my-annual-review-2019/</guid><description>&lt;p&gt;Here&amp;rsquo;s my annual professional review covering 2018.&lt;/p&gt;</description></item><item><title>Technologist Reading List</title><link>https://jakeworth.com/posts/developer-reading-list/</link><pubDate>Sat, 28 Sep 2019 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/developer-reading-list/</guid><description>&lt;p&gt;Here&amp;rsquo;s my list of favorite programming books.&lt;/p&gt;</description></item><item><title>A Short Introduction to Test-Driven-Development (TDD)</title><link>https://jakeworth.com/posts/intro-to-tdd/</link><pubDate>Wed, 11 Sep 2019 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/intro-to-tdd/</guid><description>&lt;p&gt;I&amp;rsquo;ve practiced TDD (Test-Driven-Development) a lot and feel knowledgable about when it&amp;rsquo;s useful and when it isn&amp;rsquo;t. In this post,
I&amp;rsquo;d like to summarize what I&amp;rsquo;ve learned.&lt;/p&gt;</description></item><item><title>Pangram in TypeScript</title><link>https://jakeworth.com/posts/pangram-in-typescript/</link><pubDate>Mon, 29 Jul 2019 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/pangram-in-typescript/</guid><description>&lt;p&gt;I&amp;rsquo;ve been doing Exercism&amp;rsquo;s TypeScript exercises, and wanted to share my
pangram-checking utility.&lt;/p&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>JavaScript Equality</title><link>https://jakeworth.com/posts/javascript-equality/</link><pubDate>Tue, 17 Jul 2018 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/javascript-equality/</guid><description>&lt;p&gt;A few weeks ago, I built an app with React.js and create-react-app that I call
&amp;lsquo;JavaScript Equality&amp;rsquo;. &lt;a href="https://javascript-equality.vercel.app/"&gt;View deployment here&lt;/a&gt;. This application demonstrates the JavaScript value-comparison operators &lt;code&gt;==&lt;/code&gt;
and &lt;code&gt;===&lt;/code&gt;. It&amp;rsquo;s inspired by the &lt;a href="https://dorey.github.io/JavaScript-Equality-Table/"&gt;JavaScript Equality Table&lt;/a&gt;.&lt;/p&gt;</description></item><item><title>A Git Workflow to Keep Branches Current and PRs Clean</title><link>https://jakeworth.com/posts/mgrim-everything-updated-all-the-time/</link><pubDate>Wed, 11 Jul 2018 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/mgrim-everything-updated-all-the-time/</guid><description>&lt;p&gt;My current favorite command line alias is &lt;code&gt;mgrim&lt;/code&gt;, composed of four other aliases. Here&amp;rsquo;s what it is, and what it does.&lt;/p&gt;</description></item><item><title>Comprehensive Instructions</title><link>https://jakeworth.com/posts/comprehensive-instructions/</link><pubDate>Mon, 09 Jul 2018 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/comprehensive-instructions/</guid><description>&lt;p&gt;A user opened an issue in Tilex last week that I spent a significant amount of
time thinking about and talking about (thanks JB) before responding to. Here&amp;rsquo;s
the truncated request:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;May I ask you to compile a step-by-step list to set up a running TIL
instance?&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>The Universal Programming Language</title><link>https://jakeworth.com/posts/the-universal-programming-language/</link><pubDate>Sun, 17 Sep 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/the-universal-programming-language/</guid><description>&lt;p&gt;Recently I tried to answer a question that I think is common to consider when
you&amp;rsquo;re first learning about computer programming. I&amp;rsquo;ll paraphrase:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Why can&amp;rsquo;t there be an “universal” programming language that serves all purposes?&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>How I Talk: My Guide to Tech Public Speaking</title><link>https://jakeworth.com/posts/how-i-talk/</link><pubDate>Wed, 09 Aug 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/how-i-talk/</guid><description>&lt;p&gt;I&amp;rsquo;ve been giving technical talks for a few years, and I&amp;rsquo;m speaking at the Vim
Chicago Meetup next month about integrating React with Vim. In this post, I&amp;rsquo;m
going to use that opportunity as an excuse to document my speaking process.&lt;/p&gt;</description></item><item><title>Execution Credibility: Ship, Then Signal</title><link>https://jakeworth.com/posts/its-done/</link><pubDate>Wed, 19 Jul 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/its-done/</guid><description>&lt;p&gt;As soon as you can, just do the thing you have to do, and respond with: &amp;ldquo;It&amp;rsquo;s done.&amp;rdquo;&lt;/p&gt;</description></item><item><title>Don't Build Every Feature</title><link>https://jakeworth.com/posts/dont-build-every-feature/</link><pubDate>Mon, 19 Jun 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/dont-build-every-feature/</guid><description>&lt;p&gt;There&amp;rsquo;s a detail about &lt;a href="https://til.hashrocket.com"&gt;Today I Learned&lt;/a&gt; some might
find unusual: we never added a way to delete posts from the site. Why ignore a
basic CRUD feature? We didn&amp;rsquo;t ignore it. It was intentionally omitted.&lt;/p&gt;</description></item><item><title>Work Small</title><link>https://jakeworth.com/posts/work-small/</link><pubDate>Sat, 10 Jun 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/work-small/</guid><description>&lt;blockquote&gt;
&lt;p&gt;Write programs that do one thing and do it well. –The Unix Philosophy&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;I believe in working small.&lt;/p&gt;</description></item><item><title>What We Learned Porting a Rails App to Phoenix</title><link>https://jakeworth.com/posts/tilex-progress/</link><pubDate>Mon, 05 Jun 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/tilex-progress/</guid><description>&lt;p&gt;Tilex, our Phoenix port of &lt;a href="https://til.hashrocket.com"&gt;Today I Learned&lt;/a&gt;, is
coming really well. After a personal hiatus for RailsConf prep, I&amp;rsquo;m back
full-swing. My coworkers have really been bringing quality commits as well, and
I feel we are very close to a successful port.&lt;/p&gt;</description></item><item><title>You Should Blog</title><link>https://jakeworth.com/posts/you-should-blog/</link><pubDate>Sat, 11 Feb 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/you-should-blog/</guid><description>&lt;p&gt;I created this blog to reflect on my code and development as a
programmer. In that spirit, I&amp;rsquo;d like to make a pitch to
anybody reading: you should blog.&lt;/p&gt;</description></item><item><title>Reset an Ecto Heroku Postgres Database</title><link>https://jakeworth.com/posts/reset-an-ecto-heroku-database/</link><pubDate>Sat, 07 Jan 2017 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/reset-an-ecto-heroku-database/</guid><description>&lt;p&gt;We introduced some breaking database changes to our &lt;a href="https://github.com/hashrocket/tilex"&gt;Phoenix port&lt;/a&gt; of &lt;a href="https://til.hashrocket.com"&gt;Today I Learned&lt;/a&gt; on Friday; today I deployed them to staging. Resetting an Ecto Heroku database, with new seed data, turned out to be a little tricky, and I wanted to document what I learned.&lt;/p&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 Nonrecursive Mappings</title><link>https://jakeworth.com/posts/vim-nonrecursive-mappings/</link><pubDate>Sat, 17 Dec 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/vim-nonrecursive-mappings/</guid><description>&lt;p&gt;My first PR to a new Vim plugin was merged this week, &lt;a href="https://github.com/dillonhafer/vim-termbux/pull/1"&gt;check it
out&lt;/a&gt;, adding non-recursive
Vim mappings to vim-termbux.&lt;/p&gt;</description></item><item><title>Porting TIL from Rails to Phoenix: Initial Commits</title><link>https://jakeworth.com/posts/porting-til-to-phoenix-initial-commits/</link><pubDate>Tue, 29 Nov 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/porting-til-to-phoenix-initial-commits/</guid><description>&lt;p&gt;Last week, I started a new project: porting &lt;a href="https://til.hashrocket.com"&gt;Today I
Learned&lt;/a&gt; from Ruby on Rails to Phoenix (Elixir).&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>Learn to Test</title><link>https://jakeworth.com/posts/learn-to-test/</link><pubDate>Fri, 15 Jul 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/learn-to-test/</guid><description>&lt;p&gt;What is a skill one could learn to set themselves apart from other entry-level programmers? Testing.&lt;/p&gt;</description></item><item><title>Why Elixir?</title><link>https://jakeworth.com/posts/why-elixir/</link><pubDate>Wed, 06 Jul 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/why-elixir/</guid><description>&lt;p&gt;I&amp;rsquo;ve been learning and using Elixir lately, and loving it. More than once, I&amp;rsquo;ve been asked some version of the question: why are you
learning Elixir? What makes this language unique? I thought I&amp;rsquo;d take a moment and try to distill my rationale.&lt;/p&gt;</description></item><item><title>Writing Elixir Sigils</title><link>https://jakeworth.com/posts/writing-elixir-sigils/</link><pubDate>Mon, 04 Jul 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/writing-elixir-sigils/</guid><description>&lt;p&gt;Sigils are a mechanism for working with textual representations in Elixir. If
you&amp;rsquo;ve ever made an array of Strings in Ruby with &lt;code&gt;%w()&lt;/code&gt;, the API is similar.
A neat feature of sigils is that we can make custom variants, or override
existing Kernel variants. The latter is generally discouraged.&lt;/p&gt;</description></item><item><title>How and Why to Squash Your Pull Request</title><link>https://jakeworth.com/posts/squash-your-pr/</link><pubDate>Sun, 03 Jul 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/squash-your-pr/</guid><description>&lt;p&gt;Many pull requests go through a cycle: programmer opens pull request,
maintainer gives feedback, programmer makes changes, repeat until ready to
merge, maintainer merges. Prior to the merge, the pull request can be messy,
full of reverts, fixups, and WIP commits. In the end, those commits are noise.
We can tell a better story by squashing the branch.&lt;/p&gt;</description></item><item><title>Recreating Elixir's Enum.sum</title><link>https://jakeworth.com/posts/recreating-enumsum/</link><pubDate>Thu, 30 Jun 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/recreating-enumsum/</guid><description>&lt;p&gt;I&amp;rsquo;m learning Elixir, and today as an exercise, I was challenged to recreate &lt;code&gt;Enum.sum&lt;/code&gt; using recursion. Here&amp;rsquo;s
my solution.&lt;/p&gt;</description></item><item><title>Server Side Sorting in Ruby</title><link>https://jakeworth.com/posts/server-side-sorting/</link><pubDate>Tue, 28 Jun 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/server-side-sorting/</guid><description>&lt;p&gt;Recently a friend asked me this question about server-side sorting in Rails. Here&amp;rsquo;s the question
and my answer.&lt;/p&gt;</description></item><item><title>Keyword, Match, and Region in VimScript</title><link>https://jakeworth.com/posts/keyword-match-and-region-in-vimscript/</link><pubDate>Wed, 20 Apr 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/keyword-match-and-region-in-vimscript/</guid><description>&lt;p&gt;After a recent talk I gave that included VimScript, an attendee asked a
question about the differences between &lt;code&gt;keyword&lt;/code&gt;, &lt;code&gt;match&lt;/code&gt;, and &lt;code&gt;region&lt;/code&gt;
following &lt;code&gt;syn&lt;/code&gt; in a Vim syntax highlighting file. Here&amp;rsquo;s my answer.&lt;/p&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>From One End to the Other in Ruby</title><link>https://jakeworth.com/posts/from-one-end-to-the-other-in-ruby/</link><pubDate>Sun, 06 Mar 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/from-one-end-to-the-other-in-ruby/</guid><description>&lt;p&gt;A while back I tackled the following programming challenge:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;From One End to the Other: Find the smallest possible
(positive) integer that ends in a six such that if that six is removed and
placed in front of the remaining digits of the number, the resulting number
will be four times as large as the original.&lt;/p&gt;
&lt;/blockquote&gt;</description></item><item><title>Vim Buffer Problem</title><link>https://jakeworth.com/posts/vim-buffer-problem/</link><pubDate>Sun, 06 Mar 2016 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/vim-buffer-problem/</guid><description>&lt;p&gt;A few weeks back I tackled the following programming challenge from my colleague Josh Branchaud:&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;Vim Buffer&lt;/p&gt;
&lt;p&gt;I open up a new Vim buffer and type all the numbers 1 to 10,000,
separated by spaces. Then, my cat walks on the keyboard and somehow activates
a substitution command that replaces all the &amp;lsquo;0’ digits (zeros) with spaces.
If I now sum up all the numbers in the buffer, as delineated by spaces, what
is the total?&lt;/p&gt;
&lt;/blockquote&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>Building a Markov-Chain MVP in Ruby</title><link>https://jakeworth.com/posts/ceramic-nation/</link><pubDate>Fri, 11 Sep 2015 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/ceramic-nation/</guid><description>&lt;p&gt;Project announcement! Last night I built a &lt;a href="https://en.wikipedia.org/wiki/Markov_chain"&gt;Markov Chain&lt;/a&gt;-generated
novel, titled &lt;em&gt;Ceramic Nation&lt;/em&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>The N + 1 Problem</title><link>https://jakeworth.com/posts/n-1-problem-and-n-plus/</link><pubDate>Sun, 22 Feb 2015 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/n-1-problem-and-n-plus/</guid><description>&lt;p&gt;Recently, I was thinking about the N + 1 problem. N + 1 is a performance issue in a web application, where a method call unleashes a torrent of database queries.&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><item><title>Ruby Symbol#to_proc</title><link>https://jakeworth.com/posts/ruby-symbolto_proc/</link><pubDate>Fri, 31 Oct 2014 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/ruby-symbolto_proc/</guid><description>&lt;p&gt;What does &lt;code&gt;&amp;amp;:&lt;/code&gt; mean in Ruby? In this post, I&amp;rsquo;ll explain.&lt;/p&gt;</description></item><item><title>The Case for One Computer Monitor</title><link>https://jakeworth.com/posts/one-monitor/</link><pubDate>Mon, 31 Mar 2014 00:00:00 +0000</pubDate><guid>https://jakeworth.com/posts/one-monitor/</guid><description>&lt;p&gt;I have one computer monitor on my desk. Not long ago, this was common, but
today, many people have two, three, or four monitors. In this post, I&amp;rsquo;d like to
make the case that most professional programmers can use just one
monitor.&lt;/p&gt;</description></item><item><title/><link>https://jakeworth.com/talks/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://jakeworth.com/talks/</guid><description/></item></channel></rss>