This is Anti-pattern—thoughts on programming and whatnot by Brandon Weiss.

Explicit Privates

May 16th, 2016

Years ago I wrote about the different styles of private declarations in Ruby and my personal preference. It was the best I could see at the time, but it was only marginally better than the rest and totally non-standard. Now I think I’ve finally arrived at a style that is superior to all of them.

To recap, the common style is this.

class Stuff

  def something_public
    # …
  end

  private

  def something_private
    # …
  end

end

Despite being ubiquitous, it’s actually awful. If your file is large, the only way to know if a method you’re looking at is private or not is to keep scrolling upwards until you either see a private or class declaration. All Rubyists have done this so many times now it’s become habitual. We’ve all internalized this as normal and we don’t ever think about how absurd it is. There’s a better way, though. If you’re a savvy Rubyist, you might be aware that the private declaration doesn’t affect class methods.

class Stuff

  private

  def self.something_private
    # Not actually private
  end

end

Never having tried to directly call a class method I’d declared as private, I didn’t discover this for years. To actually make a class method private you have to use private_class_method.

class Stuff

  def self.something_private
    # Now this is private
  end
  private_class_method :something_private

end

Which led me to realize you can do the same thing with instance methods and private.

class Stuff

  def something_private
    # This is private
  end
  private :something_private

end

And even better, the private declarations can be inlined.

class Stuff

  def something_public
    # …
  end

  private def something_private
    # …
  end

  private_class_method def self.classy_private
    # …
  end

end

This works because the return value of a method declaration is the method name as a symbol, which gets passed as an argument to private and private_class_method.

Whatever your initial gut reaction is to the repetition, it will quickly be replaced by the surprising relief of knowing immediately whether the method you’re working on is public or private and not having to jump around to find out. I’ve been using this for the last several months and it’s great. Try it—you’ll come to love it too.

Always Use Double-quoted Strings in Ruby

June 22nd, 2015

Single-quoted strings or double-quoted strings; the eternal conflict rages on.

Between years of freelancing and open-source work I get to see a lot of different codebases. The most common quote style I see is using single quotes by default and double quotes when interpolating. When I ask why I always get the same suspicious answers:

I’m going to try and settle this once and for all.

Single quotes

Style guide

There are a number of style guides, but the two most popular ones are Bozhidar Batsov’s and GitHub’s, which is based on Bozhidar’s.

Bozhidar’s enumerates the two options—using single quotes as a default and double quotes when interpolating, or just using double quotes all the time—but only recommends being consistent in whichever you choose. In a previous version he notes that the latter style is a bit more popular in the Ruby community, although I have no idea if that is true or not.

GitHub’s says to just use double quotes all the time.

RuboCop is an awesome tool built by Bozhidar that analyzes code for style guide violations. The default configuration is to use single quotes. However, Hound, a service built on top of Rubocop by Thoughtbot defaults to double quotes.

I don’t know where the idea came from that single quotes are preferred in the style guide, but if anything double quotes are preferred. At best, you could argue there is no consensus.

Performance

I understand where this myth comes from—it sounds plausible. I was going to write a bunch of benchmarks but Lawson Kurtz already did it. It’s possible there was a performance difference at some point in the past, but if there ever was, there hasn’t been for a long time.

Intent

I find this one especially curious. Exactly how long a string are we talking about? How far offscreen horizontally or vertically are these strings going that you need to be able to discern from a quote mark at the beginning or end whether or not interpolation is happening? Most of my strings fit on one line. I can tell at a glance whether or not interpolation is happening by just looking at the string.

Double quotes

Readability

My favorite reason for using double-quoted strings is that I think they’re easier to read. Single quotes are not particularly distinctive—they’re too similar to too many other characters. When intentionally looking the difference is obvious, but when quickly scanning text it’s slightly harder to parse single-quoted strings than double-quoted strings. I have no empirical proof for this—it’s just anecdotal observation—but when I point it out most seem to notice the difference.

Simplicity

If you don’t agree that double-quoted strings are more readable that’s fine, but that doesn’t mean it’s a draw and using either is equivalent. If you use both quote styles then every time you make a string you have to think about which quote style to use. You also have to change the quote style when you add or remove interpolation from an existing string. If you always use double quotes then you never have to waste any time thinking about it.

Look at that, it turns out there’s a performance difference after all.

Complex Static Sites on Heroku

May 14th, 2015

A few years ago I wrote about a simple way to host static sites on Heroku. That was great when my personal site was just one page and some assets, but it eventually grew past that. Now it’s a handful of static pages built by Middleman, as is this blog.

Hosting a static site generated by Middleman (or Jekyll) on Heroku is easier than it might seem. First you generate the static files, then you serve them. You don’t need a custom buildpack or a gem, all you need is Rake and a few middlewares.

Generating

Do not build your site locally and commit the build folder to your repository before deploying. That is gross and unnecessary.

Heroku’s Ruby buildpack will invoke a Rake task called precompile:assets during deployment if it exists. This feature is primarily for deploying Rails apps, but you can hook into it by creating your own precompile task that will build your static site during deployment.1

# Rakefile
require "rake"

namespace :assets do

  desc "Precompile assets"
  task :precompile do
    Rake::Task["assets:clean"].invoke
    sh "bundle exec middleman build"
  end

  desc "Remove compiled assets"
  task :clean do
    sh "rm -rf #{File.dirname(__FILE__)}/build/*"
  end

end

Serving

Serving a static site is usually dead simple. Rack::Static, the same middleware that serves assets like images and stylesheets can be used to serve any static file. Unless, like me, you’re very particular about your URLs and don’t want them to have file extensions.

If you want pretty URLs you’ll have to generate static files that are Directory Indexes-compliant.2 Middleman has a Directory Indexes extension and Jekyll has a pretty permalink style. Then you can use the Rack::TryStatic middleware in rack-contrib to map your URLs to the right files on disk.

# config.ru
require "bundler"
Bundler.setup("production")

require "rack/contrib/try_static"
require "rack/contrib/not_found"

use Rack::TryStatic, {
  root: "build",
  urls: %w[/],
  try:  %w[
    .html index.html /index.html
    .xml  index.xml  /index.xml
  ]
}

run Rack::NotFound.new("build/404/index.html")

Rack::TryStatic is just like Rack::Static except it will sequentially try appending each postfix in try to the URL to check if there’s a matching file on disk. If it finds a match it will serve it via Rack::Static, if not it will pass on through and serve the 404 page.

That’s it!


  1. These are the shell commands for Middleman, but if you’re using Jekyll or something else you’ll need to adjust them. 

  2. Back in the day, most HTTP servers would respond to a request for a directory (a URL with a trailing slash) by listing the directory’s contents. They also commonly had a feature called Directory Indexes that would serve an index.html file found inside the directory instead. So if you went to /foobar/ it would serve a file at /foobar/index.html. Everyone realized they could make their URLs prettier this way if they just re-jiggered their file structure a bit. This is why for a long time trailing slashes were so common in URLs. Eventually most static sites were replaced by something dynamic like a content management system or some other application. These systems look at a URL and decide what content to serve. At that point it became pretty trivial to drop the trailing slash and map /foobar onto some page with a title of “Foobar” in the database. That’s why you almost never see file extensions or trailing slashes in URLs any more; the file extension is usually implied and unnecessary, and the trailing slash was only ever a hack we used to get rid of them in the first place.