Naildrivin' ❺

➠ Website of David Bryant Copeland

Naming and API Design

A tenet of design is that things that are the same should be obviously the same, and things that are different should be obviously different. This is the most basic way to create consonance and contrast, and is a great rule of thumb when designing anything. While Rails diverges from this in an annoying way1, Angular diverges in a baffling way that makes explaining it to a newcomer head-scratchingly difficult.

† Anatomy of a Rails Service Object

I haven’t been good at blogging for a while. Most of my writing has been toward a new book (details forthcoming), but I did manage to write up how I see designing service objects for Rails applications over at Stitch Fix’s Eng Blog.

Anatomy of a Rails Service Object:

We’ve given up on “fat models, skinny controllers” as a design style for our Rails apps—in fact we abandoned it before we started. Instead, we factor our code into special-purpose classes, commonly called service objects.

The post goes over six rules of thumb that I’ve found useful, including class design, method parameter, and return values.

How to Be a Great Software Engineer in 2 Steps

  1. Understand what problem you are trying to solve. So many skip this, or don’t spend enough time on it or don’t even realize that it’s something to do. The main failure of good programmers that I’ve seen is in not knowing what problem they were trying to solve.
  2. Figure out what you need to do to solve the problem before you solve it. This can be anything from skimming the code you’re about to change to organizing your thoughts in a full-blown design document. You have to have a good idea of how you’re going to go about solving the problem in the code.

You can apply these steps to pretty much anything you need to do, from fixing bugs, to implementing features, to writing emails, to holding meetings. If you know what problem you’re trying to solve, and have a good sense of how you’re going to do it, actually solving it becomes a lot simpler and a lot easier to get right.

† What You Don’t Get With ActiveJob

Post by yours truly on Sitepoint’s Ruby section, ”What You Don’t Get With ActiveJob”:

ActiveJob provides simple solutions to two problems faced by Rails developers when writing background jobs: queueing jobs (via the ActiveJob API) and serialization of ActiveRecord objects (via GlobalID).

It doesn’t, however, help with the third problem: writing resilient jobs that can survive in a production environment.

† Why Scrum Should Basically Die in a Fire

Giles Bowkett posted a great piece on the deep flaws of Agile processes like Scrum. It’s spot-on with my experience. There’s so many choice quotes, it’s hard to pull just one, but I’ll try. Toward the end of the article:

I’ve never seen Scrum-like frameworks for transmuting the work of designers, marketers, or accountants into cartoonish oversimplifications like story points. People are happy to treat these workers as adults and trust them to do their jobs.

I don’t know why this same trust does not prevail in the culture of managing programmers.

After a job converting JIRA Tickets into Story Points into diffs, I eventually realized that good developers deliver results, not promises, points, or even features. I even wrote an entire book about it.

Thankfully, the team at Stitch Fix has no sprints, story points, velocity, or planning poker. We just solve the most important problem at hand, and move onto the next most important one.

❺➠ Rails’ Degenerate Front-End Support

Rails front-end support is pretty degenerate and I don’t understand why. By “degenerate”, I mean the mathematical notion of “so simple as to belonging to another class”. And it seems that the Rails team isn’t planning to do anything about it any time soon, as DHH has doubled-down on “server-generated JavaScript responses”.

Why isn’t Rails leading the way here? Where is the Rails that shocked the world with its elegant API for creating server-side web applications? It seems that it’s still peddling the same solutions for rich user-interfaces as it was over four years ago.

† What Makes Code Hard to Understand?

@garybernhardt linked to a short academic paper on code readability, called “What Makes Code Hard to Understand?”. It’s a quick read that details an experiment where researchers showed severals versions of the same program to a bunch of programmers and asked them to guess the output. Each version had the same cyclomatic complexity and lines of code, but differed only in formatting, variable naming, and use of types.

Choice quote:

The physical aspects of notation, often considered superficial, can have a profound impact on performance [of programmers to understand what code will do]

In particular, in a program that relied on order of operations, two versions were given, one in which one space was used around operators (zigzag) and another where the operators were all vertically aligned (linedup):

Programmers were more likely to respect the order of mathematical operations in the linedup version of whitespace, showing how horizontal space can emphasize the common structure between related calculations.

Also, they presented three versions of code to calculate the area of a rectangle, using free variables, tuples, and a Rectangle class:

Programmers took longer to respond to the tuples version of rectangle despite it having fewer lines than the class version. It is not uncommon in Python to use tuples for (x, y) coordinates, but the syntactic “noise” that is present in the tuples version for variable names (e.g., r1_xy_1) and calculations (e.g., width = xy_2[0] - xy_1[0]) likely gave programmers pause when verifying the code’s operation.

This was not something that was initially obvious to me as I learned programming, but I have come to realize the importance of typography in writing code. From my post on the subject over a year ago:

But, it’s not just the content - the code itself - that affects readability. How it’s presented matters and if we’re going to talk about presentation, we have to talk about typography.

❺➠ the Complexity of Object-Oriented Design

I can’t say what a codebase designed to Alan Kay’s idea of “object-oriented” might look like. I can say what your average developer (including myself) actually creates using object-oriented languages, tools, and techniques. The result is a constant battle to tame complexity. I’m going to lay out one source of that complexity, because it’s baked-in to object-orientation, and I debate that it provides any utility in making programs easy to understand or change.

† Dealing With Resque Failure

Over on Stitch Fix’s engineering blog, I wrote a new post on how we deal with tricky job failures. Namely, make your jobs idempotent:

Trapping Resque::TermException is really just kicking the can down the road. You might prevent some of your jobs from failing, but you’ll still get failed jobs. Granted, they will fail at a lower rate, but it’s still a rate correlated to the scale of your business.

The underlying problem is that jobs aren’t idempotent.

Check out the entire thing here.

❺➠ Thinking in Types

In a previous post about Swift, I talked about how static types were increasingly seen as important in programming language design. “Static” concerns a lot of developers, especially those using languages like Ruby or JavaScript. Let’s forget about that word and just talk about types.

What do we mean by types?

Types are everywhere, they are all around us, even now in your very programs. You can see them when you look at your browser, or when you start up your editor. You can feel them when you go to work, when you go to meetups, when you buy your conference passes.

Morpheus The Matrix (Paraphrased)

Morpheus is correct, types are at the absolute core of every program we write, “static” or not.