2017

I’m not much for resolutions… but I do have some goals for this year.

  1. Start going by Will instead of BJ. I’ve been meaning to do this for years. Decades. Going to do it.
  2. Focus on working with my kids more.
  3. Build a website with Elixir.
  4. Design 2 physical products (maybe a keyboard and a IoT planter, we’ll see).
  5. Finish my many house projects including our kitchen, fixing up the garage and building an armoire for our bedroom.
  6. Learn how to design things in 3D software. This is probably a subpoint of 4.

Sending Passbook Push Notifications with Houston and Sidekiq

The Nomad collection of iOS/Ruby tools are a great resource. I recently switched how Goldstar is sending out push notifications from Grocer to Houston.

Grocer has gone unmaintained for most of 2014, and it was obvious how to recover from a problem we were having with it where Apple would close the persistent connection we were using to send notifications, and so any notification sent after that would be lost. So I used Josh Symonds’ technique (with some tweaks I’ll mention later) to send them in a more robust way.

The one thing that Grocer does out of the box that Houston didn’t that we really needed was a way to send Passbook Push Notifications. These just like regular Push Notifications, however they are totally blank, sent to a token the pass registers with your server, and only work against the Production push notification gateway, using a different SSL certificate than your standard cert. This causes some problems because Houston assumes the Rails development environment should send pushes against the dev apple gateway.

Continue…

Lean into it

I’ve changed my mind.

First, let me step back.

For the last few years, I’ve been one of a (growing) minority of folks that has been promoting the idea of going against the grain, and not building Rails apps “The Rails Way”. In fact, I even have an unpublished draft on my blog dated June 9, 2011 called “The Downfall of Rails”. I was pretty sure Rails, as we knew it, was totally over. I haven’t been a proponent of DCI, but I have been a proponent of things like mustache, Isolate, Jammit, and a number of competing (and, I still stand by this, better) technologies. I have been one of those people who might lecture you about service oriented design, how ridiculous bundler is, and how rails isn’t actually OOP and a whole number of anti-Rails things like that if you give me the chance.

Here’s the thing. It’s actually not that helpful.

A good number of folks that read that will say “But we have to have the conversation, it has to start somewhere.” Maybe. But I feel like we’ve had it (many times, the first one being the long nightmare merb merge), and it’s just not worth having over and over again.

There are two points here, that I don’t think can be debated:

  1. DHH doesn’t care.
  2. We all chose Rails because it’s opinionated.

Those are, for better or worse, facts. And if DHH just doesn’t care, and if we choose Rails *because* we wanted opinionated software, these conversations just really aren’t that helpful.

So what am I actually suggesting here? Stop talking about “Proper OOP” and DCI (in rails) and “Objects on Rails” and whatever else falls in this category.

Here’s the deal, if you want to do “Proper OOP” (not that anyone can even agree on what that is), do it. There are frameworks and tools out there. Build something “proper” on Rack. Use webmachine. Webmachine is amazing. It’s a totally different way to think about web software and it’s pretty close to “proper oop” to me. And it’s not trying to shoe horn some idea you got on top of Rails.

But if you’re going to be a Rails Developer™, lean into it. Lets bring the conversation back to what the “Rails way” to do things is and lets grow those ideas. And lets talk about how to move Rails, keeping it’s conventions and opinions, forward. And, importantly, lets just agree that it isn’t DCI and “Proper OOP”. Because that isn’t the future of Rails. That might be the future of Ruby web apps, and that’s great, I hope it is, but it’s not the future of Rails.

Footnote: I’m not against SOLID or clean code or learning from smalltalk or listening to the great neckbeards of the past. Lets do all those things. Lets all be better programmers. I don’t think DCI and it’s ilk is any of those things.

Working Software

I’ve been thinking about what the minimum requirement for a programmer is. It’s an interesting topic. No one talks about it, really. What’s the most basic skill a programmer must possess to call themselves a “professional programmer”?

I’d like to think that we could look at some other professions and see how they define it. Doctor’s have the saying “do no harm”, pretty good. Architects, I’d guess, have to be able to design a building that doesn’t implode. Plumbers have to build a system of pipes that doesn’t get backed up and doesn’t leak. Lawyers, at the most basic level, just need to know the laws. They just need to be correct.

If you try to fix your sink, and it starts spraying water all over your kitchen, you might proclaim “I’m no plumber!”. If you gave medical advice to someone, and they got sick, you’d say “I’m no doctor!”. Almost all statements prefaced with IANAL are wrong, because that person doesn’t actually know what the laws say.

I think we could sum this up by saying, the basis of most professions is the ability to not break anything, or be incorrect in what you say.

So, what can we say about programming? How do you define what makes someone a professional? Correctness? All software that I’ve ever used has been incorrect in one way or another, so we’re going to have to throw that one out. Let’s get even more basic.

The minimum attribute of being a profession programmer is that you deliver working programs. Your code works. It does not break. It does not make things worse.

How many programmers do you know that can say that?

I would like to hear more folks would talking about “this”. Software that works. The process of delivering software that doesn’t break, consistently.

Expanding on the Law of Demeter

Recently, my friend Avdi Grim posted a great explanation of the Law of Demeter (LoD). It’s been tweeted and posted all over the web, so hopefully you saw it and read it. I’m totally in agreement with his conclusions in that post, and LoD is a code smell I see in every MVC project I have ever worked in.

I’m going to pick on Avdi’s post just a little, but this is more-so criticism of every LoD explanation I’ve ever read. I think all of these explanations of LoD are actually quite contrite and not addressing the real problem. Avdi (and others) seem to focus on “Structrual Coupling” or exposing the “internal” (actually external*) structure of your objects to other objects that don’t need to know it.

An Example:

def user_info(user) "Name: #{user.name}. Boss: #{user.department.try(:head).try(:name)}" end

Avdi does a beautiful job illustrating why this code is a problem but I want to go a little deeper.

The more insidious LoD violation see in codebases is what I’d call “behavioral” LoD violations, or, when the behavior of a class relies on the behavior of objects that are distant in the object graph.

My example needs a little setup. Lets say you have Vehicles which has_many Platforms which has_many Models which has_many Versions (and Platforms has many Version through models). Pretty simple 4 level deep object graph that a car manufacturer might have. A very common set of objects you might want is to know which Platforms are actually in production. Some our outdated, some are future, but you want all the platforms that are currently in production.

Now, I know how I’d do this, but I commonly see code like this:

class Vehicles
  def current_platforms(options = {})
    platforms = platforms.find(:all,
                        :conditions => 
                          ["platforms.on_date >= ? AND platforms.status IN ('open', 'cancelled') AND platforms.cached_inventory_status != ?",
                            Date.today.to_s(:db), 
                            Platform.cached_inventory_status(:no_inventory)],
                        :order => 'on_date asc, time_note asc',
                        :include => {:models => :versions})
  
    if options[:skip_some_special_case]
      platforms.select { |platform| platform.versions.any? { |offer| !version.special_case} }
    elsif options[:skip_some_other_case]
      platforms.select { |platform| platform.versions.any?(&:other_case?) }
    else
      platforms
    end
  end
end

This code is a great example of my problem with how most folks end up simplifying LoD violations. No where are we chaining methods “too deep” or as it gets simplified to are we “using too many periods”. We’ve only used 1 period (because of a has_many :through =>). However, in our if statements, we are tightly coupling our code to the behavior of a class that is 3 siblings away from the one we’re working in. Nasty. Never should a Platform do operations on, or even know about, a Version.

So why is my example actually worse than something.try(:something_else).try(:a_third)? Well, lets get back to that * I left on “(actually external [structure])”.

Most people seem to classify the active_record generated attribute accessors of Rails model classes as “internal structure” (Avdi doesn’t, I should state for correctness). These are most certainly external structure. You can override them and return whatever you’d like and attributes[:foo] is actually the “internal” accessor for all active_record classes. External structure, in every project I’ve ever worked in, has been the most consistent, least volatile part of the codebases. External structure almost *never* changes, and when it does, it’s typically *very* easy to change (it’s not even a refactoring, it’s just changing the messages exchanged between classes).

My example relies on behavior of a class 3 classes away. If there’s anything I’ve learned, it’s that behavior is always more volatile than structure, and as Avdi points out, LoD really starts hurting as code churns and whatever your LoD relies on changes and becomes more and more complex.

So the big question is, how do we fix this?

It’s actually a theoretically simple fix, and similar to the fixes in Avdi’s post: delegate the behavior down the object graph!

class Vehicle
  def current_platforms(options={})
    if options[:skip_some_special_case]
      platforms.reject(&:special_case?)
    elsif options[:skip_some_other_case]
      platforms.select(&:other_case?)
    else
      platforms.select(&:regular_case)
    end
  end
end

class Platform
  def regular_case
    ...
  end
  def special_case?
    models.special_case?
  end
  def other_case?
    models.other_case?
  end
end

class Model
  def special_case?
    versions.special_case?
  end
  def other_case?
    versions.other_case?
  end
end

class Version
  def special_case?
    ...
  end
  def other_case?
    ...
  end
end

Now, Platform knows nothing about versions, versions can easily change what defines the “cases” without any changes to Platform and ironically, when I made this refactoring to the original source I got this derived example from, it’s actually *more* efficient. Removing the explicit find that started the original method means that if we’ve already loaded this object graph, even outside of this method, we can keep reusing it without going to the database.

I hope this helps, and for the love of Demeter, can we stop describing it as “using too many periods”?

XP and Lean Startup in a single image

David Bland tweeted something today that I’ve heard/thought before, but reminded me of what the essence of both XP/Agile and Lean Startup are all about.

1. Identify all of the feedback loops in your startup. 2 Shorten them.

@davidjbland

David J Bland

I’ve distilled this into a single meme image. Print this out and put it on your wall.
Courage Wolf is Agile

Speaking of Turds (A Technological Term)

httpv://www.youtube.com/watch?v=yiJ9fy1qSFI

I use the term “turd” often when talking about products, either hardware or software but I’m not always sure people know what I mean.

A turd is something your company “has to do”. Sometimes they sink and sometimes they float, but they are always mandatory.

A turd can be polished and it can be of any shape or size, but at it’s core, it’s still excrement.

Turds always come from somewhere. Sometimes, usually the ones that float, turds come from good things. The right things. Things like user needs, innovation, obvious holes in the market demanding to be filled.  Many times, however, turds come from bad places, these are usually the ones that sink (and stink). Stinky turds come from fear, they come from reactions to competitors, they come from “obligations”.

Everyone makes turds. The iPod Touch is a floating turd. Apple was obligated to make it. How could they resist? They’ve sold a ton because of the branding and the apps and the advertising, so it’s a shiny turd, but a turd no less.

Most (all?) of the iPad “killers” are turds. They are reactionary. They aren’t innovations, they are year late catchups powered by software that went from being something new to a turd the day the App Store launched.

The Facebook platform was, in it’s inception, pretty awesome. It’s turned in to a turd through, what I can only imagine has been, some epic bikeshedding,  beauracracy and abuse. I bet Zuck would kill it if he could, but instead he’s “obligated” to keep it going.

I don’t even think turds are bad. Turds can be great. They can be just what a company needs. But lets call a spade, a spade, or a turd.

Typography of web applications

One of the hardest things about designing web applications is presenting the multitude of types of information that is necessary at any one time. What do you display? What do you leave out? What information is more or less important than other information? If a piece of information is actionable, how do you visually inform the user of that?

Recently Twitter redesigned their interface using a new 2 panel layout where the sidebar dynamically changes, allowing for deeper inspection into the tweets that show up in your timeline. From a design standpoint there are a number of things that are great about this. The proportions (using the golden ratio) are excellent. The metaphor of a slide out panel is excellent. The exprience over “old Twitter” for reading conversation is vastly better.

However, there are 2 things that specifically bug me about the new design:  what I’d call the over stylization of the content and an over abundance of information.

New Twitter conversation view.

This is a conversation in the side panel between two people I know. The first problem is that I think this is too much information. Here is what I see here: close link with icon, 3 tweets in two distinct styles with avatars, usernames, real names, timestamps, API client names and conversation links that link to the same conversation I’m viewing. There is also a user profile, which is in the same style as a tweet except the user’s bio is in italics. There is also links to use the original tweet in all the functions Twitter provides and the panel even goes on to list out other tweets from @bleything, however I have chosen to crop those out. Keeping in mind that my original intention was to view a conversation, and I came upon that conversation by clicking on a link in a original tweet, my goals are fulfilled but I’m also bombarded with more extraneous information than the original conversation contained.

Second, although there are probably less than 1000 characters here, and less than 420 characters of the information I requested when I wanted to view the conversation, there are no less than 12 distinct combinations of font weight, color and size.

Annotating a screen shot of new twitter to show the 12 distinct font styles.

Lets compare this with a “conversation view” from the Echofon Mac desktop app.

Echofon conversation viewI find Echofon’s conversation much easier to read, and if I want more information, such as the API Client used to post the tweet or the user’s bio, I don’t mind digging deeper through the pathways I already know exist in the app. If I like to do something with one of the tweets, hidden controls appear when I mouse over. And even though there are graphics, the UI here is cleaner and only contains 2 text styles.  Literally every piece of information or action provided in the new Twitter conversation is accessible via either 1 mouse click or hover.

Designing applications is always about more than what the app look like. It’s how the app works, what information it presents, and making sure the user can easily and clearly achieve their goals.

Pro Tip: Encapsulate logic in Rails Views for maintainability

A Rails view anti-pattern is that they very quickly turn into a nasty tangle of conditional html blocks.

Example:


<% if logged_in? && @user == current_user %>

Simple example, but what is the intention of that code? Why are you really checking for? Give that state a name.

Change that to:


def viewing_own_profile(user)
  logged_in? && user == current_user
end

<% if viewing_own_profile(@user) %>

Now you can test that helper method without resorting to rendering a view and parsing it to check if elements exist, the state you care about is named and the intention is clear.