Verbose Shell Scripts for Future You

Command line tools and shell builtins can offer both a short- and long-form way to specify options. Sometimes these are also called short and long flags, respectively. The upshot is a user experience with two ways to specify the same option. A short and terse way. And a longer, more verbose way.

$ curl -HLsS
# ⬆ is the same as ⬇
$ curl --head --location --silent --show-error

Both ways are useful, neither right nor wrong, and each with their own trade offs to consider.

Why Both?

Meme: Girl shrugging and asking, "Why don't we have both?" Why are there two ways to say the same thing?

It’s a good question. One I’ve asked too. But I’ve not found a definitive answer. Perhaps the truth is lost to history at this point?

From what I can tell, originally (i.e., the early/original *nix flavored OSes) there were only single-character options. At some point multi-character options were added, possibly via GNU.

Along the way the sheer number of options also grew, a lot. Is this a cause and effect relationship, a correlation, or pure happenstance? I don’t know. But today we have A LOT of options, and often multiple ways to express them.

Let’s talk about the trade offs and when to use each style.

Read on →

Well-behaved Ruby Objects: Equality

A “well-behaved” object in Ruby needs to understand the following:

What makes two Ruby objects “equal”?
And which version of “equal” (there are several in Ruby)?
And what makes an object usable as a Hash key?
And is that the same thing that makes them Comparable?

Because I can never seem to remember the specifics. And because my searching the Interwebs seems to find related, but not specific help. And because I’ve got this blurgh-thing… I might as well use it to help future-me (and maybe you?).

Gimme the gist

Implement hash and eql? for use as a Hash key, and then alias the eql? method to == for the expected developer ergonomics. Something like this:

class Message
  attr_reader :body, :subject

  def initialize(subject:, body:)
    @subject = subject
    @body = body

  def eql?(other)
    other.class == self.class &&
      other.body == body &&
      other.subject == subject
  alias == eql?

  def hash
    body.hash ^ subject.hash

What to know more about the specifics, or how to also make these objects Comparable? Read on, friend…

Read on →

Debugging Homebrew with Pry

Over the years I’ve written a few Homebrew formulas and sent the occasional Pull Request to update a formula or two. But I’ve never done any work within Homebrew. I’ve never needed to debug how Homebrew itself worked. Until now.

I assumed our typical Ruby debugging tools, like Pry and Pry-Byebug would work. Homebrew is just Ruby, after all. Which is true. But it’s also a bit special, and we can’t do the normal require "pry-byebug"; binding.pry tricks.

But we can, with a little poking around, still use those tools!

Read on →

In Search Of… Enumerable#transform for Ruby

In Search Of… a Ruby method with the semantics of Enumerable#map and Enumerable#inject. That is, to transform values while also having access to the prior iteration return value. Sounds odd, I know.

Given the following “value object”

class Snapshot
  def initialize(value = 0)
    @value = value

  def apply(new_value) + new_value)

I want to build an array of snapshots, based on some set of inputs. Meaning, I think I’d like something that looks like this

(1..10).transform( { |prev_snap, i|

Resulting in this

#=> [#<Snapshot:0x00007fe550d12558 @value=1>,
#=>  #<Snapshot:0x00007fe550d12508 @value=3>,
#=>  #<Snapshot:0x00007fe550d124e0 @value=6>,
#=>  #<Snapshot:0x00007fe550d124b8 @value=10>,
#=>  #<Snapshot:0x00007fe550d12468 @value=15>,
#=>  #<Snapshot:0x00007fe550d12440 @value=21>,
#=>  #<Snapshot:0x00007fe550d12418 @value=28>,
#=>  #<Snapshot:0x00007fe550d123c8 @value=36>,
#=>  #<Snapshot:0x00007fe550d123a0 @value=45>,
#=>  #<Snapshot:0x00007fe550d12378 @value=55>]

Right now, as of Ruby 2.5, I don’t know of a clean way of doing that. Clean being in the eye of the beholder, I suppose. It can be done with Enumerable#map or Enumerable#inject, but it ain’t pretty.

Read on →

Reclaim Your Domain Model from Rails

TL,DR; When building an application using Rails, I prefer to keep all my model in app/models/. I reserve lib/ for those other things - those not-my-domain-things. I’d like to explain the what and why.

Boundaries Amongst the Fields; Deep Greens Rails has a history of co-opting names, as happened when the ActiveRecord library used the active record pattern name. A similar co-opting has happened with the MVC pattern wherein many believe Rails is an example of the MVC design pattern. In truth, it’s probably closer to MVC Model 2… but I digress.

Model View What’s-that-now?

MVC stands for Model, View, Controller. In Rails-land we know what the Controllers are. And while we don’t have Views in the way that MVC meant, we do have view-templates, and we call those our views. The Model is meant to be all the things it takes to model our problem domain. As applied to Rails, the Model seems the most misunderstood/misused of the MVC triumvirate.

Read on →

The No Man's Land of Web Development

I think about the current state of web development experiences as a continuum. On one end we have traditional Rails-era web apps - full page loads, with bits of dynamism haphazardly mixed in. On the other are rich client-side JavaScript apps with their own structure and life cycles, standing alone and/or talking to an HTTP API.

No Man's Land Flanders Field France 1919.

Rails-era web apps have some great tooling and deliver a pretty nice development experience. The shift toward rich client-side web experiences has lead to some great tooling that makes for a 1st-class web development experience.

A no man’s land

Between these two approaches lies a no man’s land. The tooling and techniques are focused largely on either end of the continuum despite the large population of apps living in the middle.

Read on →

Git Clean: Delete Already-Merged Branches


To delete local branches which have already been merged into main:

$ git branch --merged main | grep -v "\* main" | xargs -n 1 git branch -d

You can omit the main branch argument to remove local branches which have already been merged into the current HEAD:

$ git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

Breaking it down

We start by getting a list of local branches which have already been merged into the current branch (i.e. HEAD)

$ git branch --merged

* main

We then pipe that to grep to match on the "\*" character, inverting that match via -v to get all merged branches sans the current one.

$ git branch --merged | grep -v "\*"


Finally we pipe that list in to xargs so we can strip apart the input and pass it on to a new command. We use -n 1 to ensure at most one argument is taken from the input to be passed to the invocation of the new command. The resulting commands that xargs will invoke are effectively

$ git branch -d add_new_user_gravatar_links
$ git branch -d assign_unique_key_to_uploads
$ git branch -d remember_the_last_activity_per_user
$ git branch -d update_kaminari_to_thread_safe_version

Pulling it all back together, we have

$ git branch --merged | grep -v "\*" | xargs -n 1 git branch -d

Deleted branch add_new_user_gravatar_links
Deleted branch assign_unique_key_to_uploads
Deleted branch remember_the_last_activity_per_user
Deleted branch update_kaminari_to_thread_safe_version

And there you have it. Go forth and clean up!

Bag of Methods Module and Grep-driven Development

Always looking for more concise ways to express ideas, I’d like to present two terms for your consideration.

BOMM |bäm| (abbreviation)
Bag of Methods Module
An anti-pattern for "sharing behavior" or "separating concerns" of an object. In practice such modules often contain code that is related in name or function, but lacking a cohesive purpose. See also: GDD.
GDD (initialism)
Grep-driven Development
A software development process that relies on searching full source code to find usages of methods and deduce intended behavior of a piece of code. Often caused by lack of coherent and cohesive design. See also: BOMM.

Thanks to fellow Highgroover, Andy Lindeman, for helping me to finally define these terms. Or at least, refine them.

Sensible Testing is About Sensible Design

If you’ve not yet seen Justin Leitgeb’s GoGaRuCo talk, Sensible Testing, go check out the slides. I hope the actual talk is posted soon; I’m sure it’s more rich and full of context.

Overall I agree with most of Justin’s points. However, I get the feeling that he, like many folks, approaches testing as a method for verifying the correctness of code. As I understand the thesis, CUPID is to testing what SOLID is to design.

While I’m not opposed to laying down some names and concepts to improve the state of testing, I don’t believe testing should be the goal. It’s not about testing. I believe testing is a tool to be used in guiding your design.

Read on →

The accepts_nested_attributes_for Un-Solution

Merry-Go-Round Why does Rails’ accepts_nested_attributes_for approach always feel so darned wrong?

My suspicion is that it feels wrong because it likely is wrong - or at least it is likely the wrong tool for the job.

An example

An accounting of a recent ride I took into the accepts_nested_attributes_for merry go round.

In order to create a Message, I have to first create the Conversation it’s a part of.

This sounds like an explicit workflow, so I’ll model it that way.

… hours later …

FFFUUU, this is too complicated! There must be an easier, more Rails-y way.

I know, Conversations can accepts_nested_attributes_for :messages. Brilliant!

… hours later …

FFFUUU, this is too complicated! There must be a simpler way.

I know, rather than shoehorning this into an overly-coupled mess I’ll model it as an explicit workflow!


Remember, easy is not the same thing as simple.

image via: