danott.website / archive / 2020

The 30 Second Habit That Can Have a Big Impact On Your Life (huffpost.com)

Immediately after every lecture, meeting, or any significant experience, take 30 seconds — no more, no less — to write down the most important points. If you always do just this, said his grandfather, and even if you only do this, with no other revision, you will be okay.

Code is sourdough (increment.com)

A great metaphor for maintaining a codebase over the life of the project.

Object Toaster (danielsen.com)

A parable on the king’s requirements and invention of a toaster.

My Tungsten Cube (thume.ca)

Something to compliment the rubber duck on a programmer’s desk.

Attention is your scarcest resource (benkuhn.net)

Great insights on how to embrace the scarcity, and use it wisely.

How to detect fullscreen mode using CSS (amitmerchant.com)

A useful technique for leaning into CSS for practical presentation needs.

I’ve been building a system that imports a lot of records from another system. The items from the other system have stable identifiers, but many other attributes will change.

In the past I’ve handled this scenario by iterating on each record, and individually “upsetting” into the local database. It would look something like

entries = RemoteSystem.new.entries
entries.each do |entry|
  attributes = entry_attributes_from_remote_system(entry)
  Entry.find_or_initialize_by(identifier: attributes.fetch("identifier").update(attributes)
end

This works fine and good, but I learned there’s a better way! Rails 6 introduced upsert_all. With this new method, many round trips to the database are replaced with one command.

entries = RemoteSystem.new.entries
entries_attributes = entries.map { |entry| entry_attributes_from_remote_system(entry) }
Entry.upsert_all(entries_attributes, unique_by: %w[identifier])

The one gotcha I’ve found so far, is that it fails if entries_attributes is an empty array. Easily mitigated with a presence check.

Entry.upsert_all(entries_attributes, unique_by: %w[identifier]) unless entries_attributes.blank?

The Big Binary blog post has a lot of great information on usage.

Duncan McDougall's Eleventy + SCSS/SASS Setup (belter.io)

Eleventy doesn’t have any processing for styles or scripts out of the box. Which is kind of a feature when you’re looking for a non-prescriptive tool. This post was helpful in creating a very simple setup for compiling sass, and getting it into the page.

I needed to rebuild some git history today. It’s never a fun task.

What I found while doing it, is that I was losing merge commits. I found this out to late, after taking a much less efficient approach. But if I ever encounter this problem in the future, the --keep-empty flag will be helpful. As in

git rebase -interactive --keep-empty upstream

I built a Rails mailer for the first time in a very long time today. Revisiting the docs, I was greeted with a signature I didn’t recall from the past.

Mailer.with(some: "params", set: "this way").email_name.deliver_later

In the past, I’d always invoked mailers with

Mailer.email_name(some: "params", set: "this way").deliver_later

The with message feels very aligned with ActiveJob.set. For things that are needed on all mailers, like the recipient, I like standardizing on this approach for communicating params into the mailer.

Help users change passwords easily by adding a well-known URL (web.dev)

Well Known URLs are a new-to-me convention that I find interesting.

Rails.env.test? is always preferable to writing Rails.env == "test". The behavior that powers this predicate method is the ActiveSupport::StringInquirer class.

This is not new information. But what was new, is finding the .inquiry method that is added to a whole bunch of objects, including strings and arrays..

"test".inquiry.test?
%w[this that other].inquiry.other?

Neat!

Style Stage (stylestage.dev)

The spiritual successor of the CSS Zen Garden.

FeedParser Gem (github.com)

A web feed parser and normalizer. Supports Atom, RSS, & JSON Feed.

Feedjira (feedjira.com)

A ruby gem for parsing RSS feeds. Supports RSS and Atom feeds.

Confident humility (greatday.com)

Whatever you’re doing, a sense of superiority will make you worse at it. Humility, on the other hand, will make you better.

The moment you think you’ve got it all figured out, your progress stops. Instead, continue to advance and improve by reminding yourself how much more there will always be to discover.

Confidence is positive and empowering, but arrogance is deadly. Be confident, but not at the expense of your respect for others.

Don’t burn up all your energy proving how great you are. Invest your time and energy being thoughtful and helpful.

See the victories not as proof of your supremacy, but as opportunities to offer more value to life. See the defeats not as personal affronts, but as chances to learn and grow stronger.

Take care not to waste your time in delusions of grandeur. Embrace the power of confident humility, and live well.

— Ralph Marston

Wavelength (wavelength.zone)

A telepathic party game

Performing meaningless rituals boosts our self-control through making us feel more self-disciplined (digest.bps.org.uk)

The discipline of gathering links and posting them to a website, for example.

The complete guide to CSS media queries (polypane.app)

An article that delivers on its title. Really helpful to put some terms and definitions around the parts of a media query that are relied on every day.

Mavo (mavo.io)

A new, approachable way to create Web applications

This is an extremely interesting idea. Make your site editable in place with a backing data store, and some markup.

A user’s guide to CSS variables (increment.com)

I’ve recently been jumping back into the world of CSS development. I’m so thankful for the invention of CSS variables, and this article is a great place to get familiarized with them.

68 Bits of Unsolicited Advice (kk.org)

From someone celebrating their 68th birthday. I’m a sucker for these kinds of lists.

Intro to CSS 3D transforms (3dtransforms.desandro.com)

The front-end heavy work I was entrenched in years ago would love the abilities that CSS provides out of the box these days.

ActiveJob Style Guide (github.com)

This Background Jobs style guide is a list of best practices working with Ruby background jobs.

This guide arrived at many of the conclusions I’ve arrived at while leaning into ActiveJob, and I learned a thing or two along the way.

Enhanced Shell Scripting with Ruby (devdungeon.com)

For those of us who like doing as much as possible in Ruby.

Famous Speeches (jamesclear.com)

James Clear’s growing collection of the greatest species of all-time.

noticed (github.com)

Notifications for Ruby on Rails applications.

Forms best practice (gerireid.com)

Easy to grok, actionable advice about how to design forms that people will fill out reliably.

A Ruby Macaroon Library (github.com)

Macaroons, like cookies, are a form of bearer credential. Unlike opaque tokens, macaroons embed caveats that define specific authorization requirements for the target service, the service that issued the root macaroon and which is capable of verifying the integrity of macaroons it recieves.

If it means I can avoid JavaScript Web Tokens, I’m interested in exploring further.

Ink 3 (vadimdemedes.com)

Building command line applications using React.

tinykeys (jamiebuilds.github.io)

A tiny library for adding keyboard shortcuts in JavaScript.

Always bet on HTML...being misunderstood (christianheilmann.com)

A great read on the promise and peril of leaning into tried and true semantic HTML.

HTML5 UP! (html5up.net)

Responsive HTML5 and CSS3 templates released under the The Creative Commons Attribution 3.0 License. If you wanna ditch the license, it’s only $19 at pixelarity.com.

Building GitHub-style Hovercards with StimulusJS and HTML-over-the-wire (boringrails.com)

For starters, I love the domain name boringrails.com. This tutorial delivers on the title of building some highly dynamic interaction with a few JavaScript sprinkles.

Inertia.js (inertiajs.com)

Self-billed as The Modern Monolith. My read is that it’s a protocol for how to structure your ajax interactions to have predictable re-rendering when receiving a response.

Polly.js (github.com)

Record, Replay, and Stub HTTP Interactions in JavaScript. A project on GitHub by Netflix.

Hourly Billing Is Nuts (jonathanstark.com)

Jonathan’s Stark’s thesis is pretty easy to grok. This has been my intuition for a long time, but he’s got the goods on how to make it a reality.

How the Blog Broke the Web (stackingthebricks.com)

Amy Hoy’s got a theory on how the web went south, and I am nodding in agreement with every argument.

Building a digital garden (tomcritchlow.com)

Tom Critchlow has some thoughts on how to build a digital garden, and I’m digging them.

Icons8 (icons8.com)

Free icons, music, stock photos, and vectors. Could be useful in a pinch.

Rails Bytes (railsbytes.com)

A mechanism for quickly adding behavior to a Rails application. Like bin/rails generate scaffold… but in the cloud.

Notes on RSI for Developers Who Don't Have It (Yet) (swyx.io)

Some practical tips for desk-work ergonomics.

Thanks to my partner in code, I learned that you can change the character that begins a comment in a Git commit message.

From the docs:

Commands such as commit and tag that let you edit messages consider a line that begins with this character commented, and removes them after the editor returns (default #).

If set to “auto”, git-commit would select a character that is not the beginning character of any line in existing commit messages.

I’m often writing Markdown in my commit messages, to leverage their legibility in other contexts. Before this configuration, headings were off limits. Now that I’ve changed my configuration with git config --global core.commandChar ";", they’re gonna be all over the place.

A byte order mark is an optional character that may appear at the beginning of a text stream. The unicode character U+FEFF can be used to signal several things to a program reading the text.

My program reading the text is Ruby’s JSON.parse. The text being read a JSON payload from the Pinboard API.

A helpful email exchange with Pinboard support is what pointed me in the right direction. A recent server upgrade began inserting the byte order mark where it wasn’t present before. It sounds like this insertion is going to be removed, because it makes the raw JSON payloads un-parsable by JSON.parse in both Ruby and JavaScript.

In the meantime, I wanted to get my parsing fixed, so I could keep my Pinboard powered links up-to-date. With the tip from Pinboard support and some StackOverflow I got my JSON parsing fixed.

  def load_remote_json
    uri = URI("https://api.pinboard.in/v1/posts/all?tag=danott.co&format=json&auth_token=#{auth_token}")
    body = Net::HTTP.get(uri)
+   body = strip_byte_order_mark(body)
    JSON.parse(body)
  end

+ def strip_byte_order_mark(potentially_unparsable)
+   potentially_unparsable.dup.sub("\xEF\xBB\xBF".force_encoding("UTF-8"), "")
+ end

This experience highlighted the tradeoffs of using vcr for tests. On the positive side, I had a cassette recording that captured the old API response. This allowed me to diff the old response and the new response to dig down and find what changed. On the negative side, I didn’t encounter the failure in parsing until it broke my link importing in production.

Tradeoffs.

stimulus-use (github.com)

A collection of composable behaviors for your Stimulus Controllers. The spirit of this effort is to bring the reusability of React hooks to Stimulusjs. Time will tell if the idea can span the paradigm differences.

Untools (untools.co)

Self described as tools for better thinking. Strategies to get you off of the screen, and into thinking.

Everything Easy is Hard Again (frankchimero.com)

Illegibility comes from complexity without clarity.

The new methods were invented to manage a level of complexity that is completely foreign to me and my work. It was easy to back away from most of this new stuff when I realized I have alternate ways of managing complexity. Instead of changing my tools or workflow, I change my design. It’s like designing a house so it’s easy to build, instead of setting up cranes typically used for skyscrapers.

Deku Deals (dekudeals.com)

Nintendo Switch price tracking and wishlist notifications

I started building something like this on AWS when I wanted to wait for Celeste to go back on sale. I’m so happy somebody else did it and I can delete those stale resources.

Spotify's Failed #SquadGoals (jeremiahlee.com)

If it sounds too abstract to be functional, it just may be.

github.com/sindresorhus/slugify (github.com)

A JavaScript utility for turning a human readable string into a slug suitable for URL.

simonwep/pickr (github.com)

A simple, multi-themed, responsive, dependency-free, and hackable color-picker library.

Poolors (poolors.com)

Generate unique color palettes.

Minimum viable dark mode (chasem.co)

Chase McCoy offers a minimal approach to begin supporting Dark Mode. I’d love to kick the tires on this and see how it handles in real life.

To be a good software engineer, become a French skeptic (karltarvas.com)

So when someone asks you for something, be it your time, thoughts, or effort, be skeptical and be French. Ask “why” and (mostly) say “no”. It’s good for you.

Railway Oriented Programming (fsharpforfunandprofit.com)

Thinking as a railway conductor serves as an interesting approach for making fault tolerant systems.

On focus, persistence, and misfortune (jamesclear.com)

The most useful form of patience is persistence. Patience implies waiting for things to improve on their own. Persistence implies keeping your head down and continuing to work when things take longer than you expect.

The History of the URL (blog.cloudflare.com)

A long read, but fun to understand the humble URL that we depend on all day every day.

What is said—church isn’t a building, it’s a people. What is done—church isn’t a building, it’s a broadcast. What is believed—church is information transmission.

Diagonal Layouts in 2020 (codepen.io)

A nice playground for diagonal website layouts. Interact-able and everything!

A Complete Guide to Data Attributes (css-tricks.com)

CSS Tricks is at it again with a focused article on an API we take for granted every day. Data Attributes are still the best-in-class solution for laying behavior onto Plain Old HTML.

Paged.js (pagedjs.org)

Conventions for laying out PDF printable content. Could prove useful when you get around to writing that book.

Hanami::API on Amazon AWS Lambda (lucaguidi.com)

A very compelling idea for serving a Rack application on AWS Lambda. As long as the Ruby footprint is small enough, I think this could be a really nice deployment story!

In an 8-Hour Day, the Average Worker Is Productive for This Many Hours (inc.com)

The number behind the clickbait title is 3. 3 hours out of 8. If you focus for even half the time, you can stand out.

How to test static sites with RSpec, Capybara, and Webkit (nts.strzibny.name)

I’ve long had this idea in the back of my mind. It’s nice to see it executed elsewhere, and establish a baseline for the usefulness of automated test on even “simple” projects.

Understanding CSS Grid: Grid Template Areas (smashingmagazine.com)

I haven’t had a chance to dig in on CSS Grid. A quick glance suggests that it’s the tool I’ve wanted many times in the past.

How I MITM'd rubygems.org ... Kinda (gavinmiller.io)

A really fun investigation into how much damage you can do with one person’s typo.

Mirage JS (miragejs.com)

“An API mocking library for frontend developers”. Seems powerful for stubbing out all kinds of data that will eventually have a real source.

Being a skeptic is tiring.

Inversion: The Crucial Thinking Skill Nobody Ever Taught You (jamesclear.com)

James Clear of Atomic Habits fame offers up this nice little insight on the power of looking at things from the opposite angle

Greed Rules Everything Except Nature (freeskatemag.com)

A skate video. Released in 2020. Feels strait out of the 1990s. Nostalgia weighs heavy.

StimulusReflex (docs.stimulusreflex.com)

An interesting idea for building on top of Stimulus, ActionController, and ActionCable to coordinate patterns of server-client communication. HTML-over-the-wire sounds good to me.

Bit Brigade performing Mega Man 2 (youtube.com)

This is my kind of performance art. Mega Man 2 holds a special place in my heart, and I fully endorse this message.

@suspiriadam on The Oscars (twitter.com)

not a single oscar nomination for Carly Rae Jepsen’s EMOTION… just because it “isn’t a film” and “came out in 2015”…disgusting

This will be an evergreen tweet in my book. Emotion is the album of the millennium.

Needing to reduce a pathname into the filename without it’s extension is something I need to do often. But not too often. Just often enough to forget how I last did it, and clobber together a solution anew.

So this time I’m writing down the briefest solution I’ve found in Ruby, in hopes that it’ll commit to my memory.

require "pathname"
pathname = Pathname.new("~/some/path/to/the/mountains.jpg")
pathname.basename(pathname.extname).to_s # => "mountains"

Pathname is a great tool in the standard library.

strftimer (strftimer.com)

A Ruby strftime generator. Type in the desired human readable format, get back the strftime formatting string.

Sometimes you install one gem.

gem install bundler

Sometimes you install it with a specific version.

gem install bundler -v "2.0.2"

Sometimes you install multiple gems.

gem install bundler minitest

But what do you do if you need to install multiple gems with specific versions? It is possible with a special syntax!

gem install "bundler:2.0.2" "minitest:5.13.0"

Something I really like from React Native is the global variable __DEV__. Being able to do things only in the development environment is quite handy. This concept is not unique to React Native, but that’s where I was introduced to it.

I’ve found myself in need of a similar strategy while building this static site in Rails. I have some dynamic interactions that I can use to curate content on my own machine, but I don’t want those scripts bloating the static build that is deployed to production.

This can be achived in Rails with webpacker using Webpack’s DefinePlugin!

// config/webpacker/environment.js
const { environment } = require("@rails/webpacker")
const webpack = require("webpack")

environment.plugins.prepend(
  "Define",
  new webpack.DefinePlugin({
    STATIC: process.env.NODE_ENV === "production",
  }),
)

module.exports = environment

5 Tips for More Helpful Code Reviews (thoughtbot.com)

A brief introduction to making yourself a more valuable code reviewer.

NEON PALM MALL (youtube.com)

Today I learned that vaporwave is a genre of music, and I am into it.

Stanford Encyclopedia of Philosophy (plato.stanford.edu)

Seems like a good place to start a basic study of philosophy.

The Parable of the Mexican Fisherman (renewablewealth.com)

I’ve heard this parable in a variety of contexts, and no one seems to know the origin. At least this link provides a place where it’s written down succinctly.

Why is modern web development so complicated? (vrk.dev)

A great explanation of how we got to where we’re at as an industry.

Internal Requests in Rails (coderwall.com)

def internal_request(path, params={})
  request_env = Rack::MockRequest.env_for(path, params: params.to_query).merge({
    'rack.session' => session  # remove if session is unavailable/undesired in request
  })

  # Returns: [ status, headers, body ]
  Rails.application.routes.call(request_env)
end

This is the method I built on top of for building a static site generator in Rails.