Web Framework Comparison Matrix

web framework comparison keyThis is how I evaluate frameworks for clients and my own projects. I’m doing my best to be:

  • opinionated about which features matter
  • unopinionated about the actual frameworks

So you’ll be most likely to find this helpful if you value the same things I do: good CRUD support, good deployment and testing support, and an open and friendly community. Here’s the current matrix, and a link to the spreadsheet online. Help me fill in the remaining items by leaving comments.

web framework comparison matrix 1

web framework comparison matrix 2

I’m thinking about how to preserve the sources and reasoning for each score.

Goodbye “X for Y”: the cryptic Ruby error is becoming friendlier

Anyone who’s used Ruby has seen this message:

r.rb:1:in `name': wrong number of arguments (3 for 2) (ArgumentError)

This particular error has been driving me nuts for years. It’s just so unnecessarily difficult to interpret — especially if Ruby’s not the only language you use. I never remember which number is which.

Compare to Python:

TypeError: name() takes exactly 2 arguments (3 given)

This is better in several ways. The unambiguity; the tone (no “wrong”); the lack of line-noise characters; the plain-English sentence. Note also that the numbers are presented in the opposite order from Ruby. Not a problem in itself, but it makes the Ruby equivalent especially hard to interpret because it requires memorizing the difference.

Potentially as soon as Christmas, though, Ruby’s output look will look like this:

r.rb:1:in `name': wrong number of arguments (given 3, expected 2) (ArgumentError)

This is a great step in the right direction.

It turns out that the issue had been raised two years ago. I gave the topic a bump, and Martin Dürst quickly commited the improved code. I am incredibly appreciative, and happy to see that core Ruby developers value improvements like these. In fact, there’s an open Request for Comments on improvements to Ruby’s error messages.

Ruby needs these kinds of improvements to compete with the incredible array of new, improved languages. I hope to see it become even more user friendly. It doesn’t need to look like Python in order to be more usable.

Infographic: OS X El Capitan License in Plain English

Shortly after I posted OS X El Capitan License in Plain English, I received an email from Bogdan Rauta, a Romanian infographic designer. He volunteered to create an infographic as part of a new project, Infographic Monster News. His idea is to report current news stories in the form of infographics. I’d say he’s off to a good start:

OS X El Capitan License Infographic

Follow my Patreon project for news about upcoming In Plain English posts.

OS X El Capitan License: in Plain English

I decided to upgrade my Mac to El Capitan, but my computer said, on one condition: I must “carefully” read and agree with something. It even provided a tiny cozy display window for viewing it:

OS X El Capitan License dialog

And so I did what anyone else would: I cleared my afternoon schedule and got right down to business; reading, carefully, the entire document. It turns out that I was much too pessimistic! I needed only 33 minutes.

I should note that I’m an attorney with a good understanding of license, trademark, and copyright law. I’m also a software developer with 20 years’ experience. So your own read-through may take more or less time, accordingly.

I thought it’d be a “fun” project to see what the “El Capitan License” actually says. Cool idea, huh? Kind of like spelunking through a cave that everyone says they’ve been through, but maybe no one really has. What will I find wedged in a wall or lurking in the dark around the next turn?

Update: Now in infographic form!
Update: Now as an infographic!
  1. I can’t use the Capitan with illegal copies of anyone’s stuff.
  2. Apple didn’t sell me this software. They still own it, in fact. I’m just borrowing it.
  3. If I install more Apple software, those are on loan as well.
  4. I can use the Capitan in two virtual Machines, and on one computer.
  5. But these VM’s cannot be used for business. The only exception is for software developers (I guess they wouldn’t follow this rule anyways.)
  6. I’ve got to read the separate rules that came with the fonts, and obey them. (I can only borrow those too.)
  7. Those cool voices for the clock? — no remixing!
  8. Slideshows made with Photo; same deal, don’t even think about using them for some commercial purpose.
  9. I can’t sell access to my Mac via any kind of screen sharing.
  10. I gotta run it on Apple hardware (no Hackintoshes).
  11. I can’t help anyone else do that.
  12. I can make one copy as a backup.
  13. I can’t try to figure out the source code to any of this.
  14. I gotta follow all my local laws while I’m using it. (!) (Really? Whereever I live?)
  15. can leave the software on the Mac if I sell it or give it away.
  16. I better not use anyone else’s hacked version.
  17. Apple isn’t responsible for my hurt feelings for anything I see on the web.
  18. If I break any of these rules, this deal is over and I must immediately delete everything.
  19. The Capitan comes as-is.
  20. I can’t send it to Sudan.
  21. I can’t operate a nuclear power plant with it.
  22. I cannot, don’t even think about it, just plain can’t, make money from MPEG/H.264/AVC videos I create. For that, I need to buy another something from somebody.

There you are. I took one for the team.

UPDATE: Thank you to everyone for the great positive response and encouragement to write more. I’ve set up a Patreon account to help support me to write new posts weekly. Everyone who pledges, even $1/month, gets access to a private forum where I answer questions about the plain-English translations.

Please consider sponsoring this new, awesome project.

git commit –amend: Have Your Cake and Eat it Too

For a lot of us, version control does two things which are contradictory:

  • it keeps checkpoints as we work so we can easily roll back, and
  • wraps up our work into a tidy package for others to use.

git commit --amend is one tool that solves this. It will “open up” the previous commit, adding staged files and allowing you to re-edit the commit message.

  1. Make your “checkpoint” commit, e.g. with a failing spec.
  2. Get your specs working again.
  3. Stage your changes like you normally would using git add.
  4. Instead of git commit, do git commit --amend.
  5. Edit the message to describe the feature. This will be the commit’s new message, and it will contain all the changes.

A related command: git rebase -i  (“interactive”). If you didn’t use --amend, you can go back and condense commits together as if you had. With this command, you can interactively rebase, using the “squash” command to combine multiple commits together.

A Benefit of Rails: Surrogate Keys

Today I helped a client wrestle with a database task which concluded:

. . . We’ll have to watch out inventing new “fake” customers because one day there may be a real customer with our made up ID :-(

This is a problem in lots of apps, but not in Rails.

Rails enforces the “best practice” of giving every table a primary key named id, which is an auto-incrementing integer. But many non-Rails apps do not do this. Instead, they use some real-world data as the primary key. This is called a natural primary key. E.g., a customer’s social security number. There are arguments for and against this. This is a good little wikipedia page about the differences.

One big problem with natural primary keys is that they often turn out to not be as unique as we think. Plus, then we’re put in the position of “faking” the SS number when we want to manually add customers who don’t have one, e.g. “999-….”. (I remember a college I attended which assigned 999- SS numbers to international students.) And this is the hack that the task description refers to.

In contrast to natural keys, the id field is a so-called surrogate key. It intentionally has no meaning in the real world, and so it has no reason to ever change. It doesn’t matter at all what an object’s id is, just so long as it’s unique. And since it gets set up as an auto-incrementing integer, that will be the case.

So, Rails is “opinionated software” and has made the decision for us. Every table will have;

  1. a surrogate key,
  2. named id,
  3. which is an auto-incrementing integer.

And in one swoop, a whole category of potential problems is eliminated. Secondly, this makes it very easy to get up to speed on a new Rails app.

Self-validating Ruby objects with ActiveModel Validations

I’m importing lots of CSV restaurant inspection data with Ruby, and I need to make sure the cleaned up data matches the spec. For example, a violation must have a business_id and date. It can optionally have a code and description. My goal was to be able to write a class like this:

class Violation < ValidatedObject
  attr_accessor :business_id, :date, :code, :description

  validates :business_id, presence: true
  validates :date, presence: true, type: Date

…and it would just work, Rails-style:

Violation.new do |v|
  v.business_id = '1234'
  v.date = '2015-01-15'
# => ArgumentError: date must be of the class Date

Violation.new do |v|
 v.date = Date.new(2015, 1, 25)
# => ArgumentError: business_id is required

Violation.new do |v|
 v.business_id = '1234'
 v.date = Date.new(2015, 1, 25)
# => new instance Violation<...>

ActiveModel::Validations was refactored out of ActiveRecord to enable just this sort of use case. This is because the awesome list of built-in validations (here and here) and methods like #valid? are useful in a variety of contexts, not just in Rails.

It turned out that it was easy to write a small base class with the ActiveModel::Validations mixin to make the checking automatic upon initialization:

require 'active_model'

class ValidatedObject
  include ActiveModel::Validations

  def initialize(&block)

  def check_validations!
    fail ArgumentError, errors.messages.inspect if invalid?

For my importing and parsing purposes, I created a small custom TypeValidator:

 # Ensure an object is a certain class. This is an example of a custom
 # validator. It's here as a nested class for easy access by subclasses.
 # @example
 #   class Dog < ValidatedObject
 #     attr_accessor :weight
 #     validates :weight, type: Float
 #   end
 class TypeValidator < ActiveModel::EachValidator
   def validate_each(record, attribute, value)
     return if value.class == options[:with]

     message = options[:message] || "is not of class #{options[:with]}"
     record.errors.add attribute, message

Here’s the finished ValidatedObject, and an example subclass: information about a CSV feed. This set up is working great; the only change I can see making soon is changing ValidatedObject to be mixed in via include rather than subclassing.

Thanks to:

The problem with packaging in Python

Excellent article. We got to this situation because of the changing nature of writing software, and how we deploy. Our standards have risen, and packaging (and tooling in general) takes on ever greater importance.

But we don’t have to theorize and invent paradigms from scratch. A few other languages have solved this. Ruby is the best example. Let’s learn from its user experience and the use cases it serves.

Python project organization, circa early 2015

The best, current guides I’ve found

It’s hard to find current best practices for organizing a reusable python package. I’m starting a new project to get the world’s restaurant health scores online, and so searching for some kind of guide, these are the best I found.

Degrees of freedom: Four valid ways to write degrees Fahrenheit in HTML

I was working on my startup’s food safety score web app, writing code to clean up imported text like,


We decided to make this as readable as possible without changing the content. And so, the finished text should have improved capitalization, punctuation, and typography:

Screenshot 2015-01-19 17.02.00

The interesting part was the temperatures. First I looked for a style guide because I realized I didn’t even know how a temperature should be punctuated; e.g. should there be any spaces within it? The National Geographic Society’s style manual was a good match for us. It prescribes no space between the final digit and the degree symbol:

F is the abbreviation for Fahrenheit: 32°F (no spaces, no period)

I then discovered four different, valid ways of writing this in HTML, each producing unique results:

Strategy Code Screenshot
HTML entity for degrees Fahrenheit #&8457; 1
HTML entity for degree symbol with a normal F &deg;F 2
Unicode degrees Fahrenheit character 3
Unicode degree symbol with a normal F °F 4

Notice how the fourth option both looks the best and it’s the easiest to read in the HTML source. That’s what I went with. Clearly there’s an interaction between the browser, the font, and the implementations of these protocols.