September 2nd, 2007

David Hansson used the phrase "junk in the trunk."

This is why we ♥ David.

February 23rd, 2007

A body of techniques for investigating phenomena and acquiring new knowledge, as well as for correcting and integrating previous knowledge. It is based on gathering observable, empirical, measurable evidence.

That’s how the venerable Wikipedia defines the scientific method. In one of my former careers, systematic observation (through tests and repeated replication of results) was inherent in our every activity. Yet when I took to learning programming, I somehow forgot that the these methods aren’t just useful for gathering knowledge about the natural world, but about everything—including the digital world.

This realization came to me as a little flash of light while reading my brilliant former instructor Mike Clark’s post titled ‘Are you there world?,’ which suggests testing as a first step in learning Ruby. For better or worse, this is actually the exact inverse of the way most of us learn languages and frameworks. Testing is usually one of those things that we intend to get around to someday but never quite take the time to learn properly—something to do at the nebulous “end” of your big project as a way of making sure things aren’t breaking in production. I had fallen into this trap as well. I learned Ruby mostly by randomly stumbling around, trying new things in attempts to build little sandbox projects. There was nothing systematic about this, nor was there any attention to replication of my results. (Most of it involved lots of browser refreshing.) Somehow, I had forgotten the scientific method as the path to knowledge.

Mike, however, advocates what could certainly be called a scientific approach to learning Ruby, based on what are effectively systematic, repeatable, language experiments. He challenges us to put the computer in charge of remembering all the experimentation we do when we’re first learning a language, by writing tests for all the new functionality in the language that we learn as we’re learning it.

Tests, after all, are statements of an expectation followed by a verification that the actual results of an operation evaluate to that expectation. When we’re first learning, we poke at Ruby with a stick (irb) and see how it reacts. Mike is merely suggesting making these observations systematic and repeatable—recording how the subject reacts for posterity so you’ll be able constantly to review and verify what you’re learning about it. Think of yourself as a scientific pioneer who has discovered a completely new and sophisticated organism (in our case, Ruby). Earn that lab-coat of yours: keep good records of your findings!

I’m going to stretch the concept of “replication” from the scientific method a bit here, but I think it also applies as a metaphor at least. The idea is that when you have language tests in place to record what you’ve learned, you always know when your knowledge becomes invalid. When your expectations fail, you have something new to learn. For example, things are in constant flux in the Rails core code base. In 2.0, old ways of doing things are going to start breaking. If you’ve kept a record from the beginning of everything you know about Rails (in the form of an executable test), all you have to do is update your version of Rails, run the test again, and you’ll know everything that you have to learn over again simply by seeing what fails.

I just have one objection to Mike’s article. His article is all about encouraging people to use Ruby’s built-in Test::Unit framework. As it happens, Test::Unit is the main reason I went so long without ever learning testing in the first place. It’s syntax is weird, ugly, and requires significant mental backflips in order to understand what you’re trying to express. This isn’t what we spoiled young Rubyists are accustomed to. Let’s take a look at a gently modified example from Mike’s article

1
2
3
4
  def test_length
    string = 'abc'
    assert_equal(3, string.length)
  end

For those of us used to expressions like 2.days.from_now, this reads as utter gibberish: “test length assert equal 3 string equaling ‘abc’ length” That doesn’t make sense in any dialect of Engrish, Franglais, or Spanglish I’m acquainted with. But there is no need to succumb to this aphasia virus; there’s hope.

That hope comes to us in the form of RSpec, the new hotness in the Ruby and Rails testing world. Now, I should preface my discussion of RSpec by warning that most of the people who like to write about RSpec are given to a certain form of intellectual onanism, which forces them to insist on all manner of esoteric precepts and justifications for their framework. Watch out in particular for citings of the Sapir-Whorf Hypothesis, which doesn’t relate to the House of Mogh but rather a unjustifiably baroque way of expressing the simple idea that the the sort of language we use affects the way we think. Put even more simply, it’s better when we express ideas in a way that makes sense.

And that’s really what RSpec is all about: expressing tests in a way that makes sense. Let’s rewrite our Test::Unit example in RSpec terms:

1
2
3
4
5
6
7
8
context "A String" do

  specify "Should return the number of characters it contains when sent the message 'length'" do
    string = "abc"
    string.length.should_equal 3
  end

end

How does that read in English? Well, we could run the file from the terminal with spec ruby_spec.rb -cfs and we’d get a nicely formatted answer in the output.

A String -Should return the number of characters it contains when sent the message 'length'

(In fact, if you do sudo gem install redgreen, you’ll even get that second line in green if its spec passes, or red if it fails.)

Or, alternatively, just read the code itself, “A string should return the number of characters it contains when sent the message ‘length’: string equaling ‘abc’, length should equal 3.” How does that compare to “test length assert equal 3 string equaling ‘abc’ length” Yes, it’s more verbose, but that’s because it actually expresses an intelligible idea.

Incidentally, this syntax gives us the added advantage of rendering us so pliant and at ease with tests (because they’re not expressed in such a weird backwards-thinking way) that it feels much easier actually to write them before we write the code we want to test. This test-first approach is something many of us believe to be a vastly superior way of doing software design (aka Behavior Driven Development, or BDD, aka Test Driven Development, or TDD). This delay-of-gratification approach to coding normally requires significant restraint and patience, but with RSpec, it just feels right. Expressing tests/specs/expectations (or whatever you want to call them) in an intuitive way makes it easier to think about how you want your application to behave, allows you to specify that behavior, and then test that it meets the specification in what feels like natural language.

As an aside, there are those who, in order to protect the new hotnessness of their respective fiefdoms, will flip their wigs at the mere suggestion that TDD and BDD are similar/interchangeable concepts. You’ll have to forgive their casuistry. They mean well.

Now that I have this whole new, completely intuitive way of expressing and testing expectations in Ruby, I find myself actually writing tests all the time, for everything. Both as a learning tool and as a design tool. Now, I’m working with my pals over at The Edge Case to learn more about its advanced features, like “mocking,” “stubbing” and other tricks to help me avoid those nasty Rails fixtures. So look for more reports from the frontiers of RSpec science here in the future.

Mike Clark is right: the scientific approach is the best way to gather knowledge (and by extension to learn Ruby). There has just been a little paradigm shift in our scientific approach. Give RSpec a try, and see if it doesn’t make that lab-coat fit a little more comfortably.

5 comments »
January 24th, 2007

I stumbled today on an apparently little-known method in Rails, which solved a problem that has been vexing me for months: how to use helper methods from controllers/models/views/whatever other than the one you’re currently working in. No amount of Googling or begging for suggestions in the (mostly useless) #rubyonrails IRC channel could do me any good.

Ok, so on Lovetastic, we have an account dashboard which pulls together lots of information from different models. This dashboard (for now anyway) rests in AccountController. However, I want to use a formatting helper to display a human-friendly version of people’s subscription expiration dates, the code for which rests in SubscriptionHelper. And I don’t want to have to duplicate any code to do it.

The helper in question, natch, is associated with a separate controller, so its methods don’t get mixed into the AccountController. So I had been trying all sorts of stupid and ugly hacks to include that helper code cleanly into the AccountController’s dashboard view. I tried using shared partials, raw ruby includes, and a couple even more arcane backflips, to no avail.

Then, with hours of sufficiently creative Googling, I was able to turn up a super-tidy Rails Way™ to do this.

1
2
3
4
5
class AccountController < ApplicationController
  helper :subscription

  ...
end

And, bam. There you have it. You can now use all the helper methods in SubscriptionHelper anywhere in an AccountController template.

Who knew?

7 comments »
November 2nd, 2006

While nginx has been covered here before, it seems the blogosphere is a bit lacking in covering a nginx + ssl + rails setup, which requires a little bit of putting 2 and 2 together and getting 5. The configuration is as such:


server {
  listen 443;
  ssl on;
  # path to your certificate
  ssl_certificate /etc/nginx/certs/server.crt; 
  # path to your ssl key
  ssl_certificate_key /etc/nginx/certs/server.key; 

  # put the rest of your server configuration here.

  location / {
     # set X-FORWARDED_PROTO so ssl_requirement plugin works
     proxy_set_header X-FORWARDED_PROTO https;

     # standard rails+mongrel configuration goes here.
  }
}

The kicker is the proxy_set_header line—it is crucial to allowing your Rails app to know whether the request was sent over http or https.

You will note that there is no server_name directive—this is because it is impossible to do name-based virtual hosts when doing https. You must have a separate IP address for each ssl host—you can specify which IP address to use (if your machine has multiple assigned IPs) by modifying the the listen directive, e.g. listen 101.102.103.104:443.

On a related note, here at Agora Games we recently launched our first production site running on nginx and Rails!

Addendum (13 June 2007): It is worth noting that Ezra’s excellent nginx configuration includes an ssl section, although it unfortunately lacks the ssl commands themselves.

10 comments »
August 27th, 2006

There are a nauseating array of options to choose from when deciding how you’re going to stick your Ruby on Rails application up on a web server. There is no real canonical formula (yet), and depending on your needs, there may be multiple passable options—though none of them are entirely pretty or elegant.

The most common stack for a while was Apache or Lighty using FCGI. The release of Mongrel has completely changed that. Mongrel is in itself a very basic web server, similar to WEBrick. Mongrel is capable of serving up your Rails application over HTTP without FCGI. Unfortunately, it is very limited (can’t host multiple sites, doesn’t have a rewrite library, doesn’t support SSL, etc), so in most cases you’ll have to stick another server out in front of it to handle those things and then proxy Rails requests over to Mongrel. So, the question is, what do you put out in front of Mongrel to proxy requests?

I’m not going to discuss all the options, but if you’re looking for what appears to be (at the moment) a setup that is a breeze to install and will churn out more requests/second than anything else, read on.

Read the rest of this entry
17 comments »
August 24th, 2006

WARNING: This seems to have messed up ri on my system. The new documentation is there, but some of the old documentation seems to be missing. `ri Array` yields no info, for example. So, please use carefully!

Would you like to be able to search and access the Rails API documentation offline via the Ruby command line utility ri? All you need to do is install RDoc for all Rails related gems. Note that this will take a while.

If you would like this to run faster, remove old versions Rails with the gem cleanup command. Note that this WILL remove old versions of Rails from your computer.

  1. remove old gems so that you don’t install RDoc for them sudo gem cleanup

And to install the documentation:

  1. cd to the rubygems directory cd `gem environment gemdir`/gems
  2. turn on extglob shopt -s extglob
  3. run rdoc -Y in every gem’s subdirectory, other than the rails dir for d in !(rails)/; do cd ”$d”; sudo rdoc -Y; cd ..; done

Now you can type `ri link\_to` and get all the API documentation on the Rails function `link\_to`.

0 comments »
August 18th, 2006

Hello, my name is JD, and I have been a professional Rails developer for about a year. Over the past several months, I have also been helping Ryan build Lovetastic. I'll usually be posting content of a more technical nature, but I hope to keep my posts understandable for all.

Rails developers are beginning to find themselves lost in a sea of multiple deployment options. Mongrel is the up-and-coming deployment option for Rails, while FastCGI is quickly becoming the dinosaur. It seems likely that by the time Rails 1.2 rolls out, Mongrel will be the recommended way to deploy into production. To bring myself up to speed, I recently spent some time learning more about Mongrel, the latest and greatest way to get your Rails app running smoothly.

Read the rest of this entry