Adam @ Heroku
a tornado of razorblades

What Defines the Ruby Community?

April 29, 2008 at 10:18 PM

A friend of mine, who is a Ruby developer but a little less immersed in the Ruby culture than I, was recently boggling at the excitement around the new VMs (Rubinius, JRuby...) and new frameworks (Merb, Sinatra...). "Wait," he said. "They're replacing Ruby, and they're replacing Rails. So what the heck defines the Ruby on Rails community, if both Ruby and Rails are replaceable?"

Good question. Peter Cooper wrote "'Ruby' is starting to represent both a community and a language 'ideal' rather than just a single, well-defined programming language." I agree. But what are the specific traits that bind the Ruby community together?

I suspect that there will be surprising divergence of opinion on this subject. But here's my answer, in the form of a two characteristics that I believe all Rubyists share.

First, Rubyists love elegance. We want to solve problems in a simple and elegant fashion. Most programming languages and software infrastructure feels like the inside of a industrial revolution-era factory: it gets the job done, but it sure ain't pretty. Rubyists create things that have the minimalist and pleasing aesthetic of a haiku or a Zen garden. We are so committed to elegance that given the choice between an inelegant solution and none at all, we typically choose the latter.

The second, and more subtle point: Rubyists are dynamists. We have a deep understanding of the infinite series of technological progress: each stage of advancement building on the next. There is no such thing as perfection: anything and everything can be improved upon. In this, we are not afraid to swap out any component with a superior replacement. Apache giving way to Nginx, Subversion giving way to Git, Prototype giving way to JQuery, Mongrel giving way to Thin, Test::Unit giving way to RSpec. Even our most fundamental foundation components - Ruby and Rails - are not safe, if someone can build better replacements.

Comments: 0 (view/add your own) Tags: ruby

Curators

April 24, 2008 at 04:45 PM

During a presentation I gave last month, someone asked what Heroku plans to do about the many different versions of Rails and Ruby, not to mention choices on components like database (MySQL, PostgreSQL, SQLite) or app server (Mongrel, Thin, Ebb).

I answered that this is part of the benefit you get by using Heroku. (In corporate-speak, part of our "value-add.") We select the best components, from the server infrastructure and operating system up to the version of Rails and preinstalled gems and plugins. We make sure it all works together in a complete package, so that you can just dive in and start coding, without worrying about making a bunch of choices before you even begin.

Another company that works this way is Apple. Apple doesn't make motherboards or video chipsets or drives. What they do is select all of the best OEM components and put them together into a beautiful package where all the parts are guaranteed to work seamlessly together. You never worry about your monitor not supporting the sync rate your video card wants to use, or whether you'll have drivers for your DVD writer, like you would with a build-it-yourself PC.

A similar metaphor, but in the software world, is the makers of Linux distributions. This is actually quite close to what we're doing: bringing together lots of open source components into a unified bundle, where all the pieces have been tested as playing nicely together. Given the fast pace of software development and the huge variety of different pacakges, this is quite a challenge - and an ongoing one.

Todd Hoff did a writeup on my presentation, and he mentions the term "curator" to describe companies or people that fill the sort of role I've just described. I think that's a pretty good term - Apple, Linux distributions, and Heroku all fit into this category.

My current favorite distros are Debian on the server and Ubuntu on the desktop, and they both do a great job at this collector role. But I think it's worth looking at another player, Red Hat, to see how this role can be done both right and wrong.

A few years ago, Red Hat was the distro to beat. Red Hat 7, 8, and 9 were all stellar releases. Then they split their distro into two forks: Red Hat Enterprise and Fedora. This seemed like a logical step: provide a slow-moving, highly stable version for production server environments; and a more cutting-edge version for desktops and personal or staging servers.

But this turned out to be a disaster for their market share: nearly overnight, Red Hat went from the most popular distro by far to a distant third. (The move may have been good for their revenue or profitability, I can't speak to that.)

Understanding why this happens helps us understand the role of a good curator. Having a single distro meant that Red Hat had to balance pushing the technology envelope against keeping things stable. In those days they did a great job at finding the sweet spot. Many people complained when they introduced major new infrastructure like glibc2 or UTF8, but in my opinion their timing was exactly right. Sure, it caused some transitional pain for users - mostly proprietary binaries like Adobe Acrobat and Yahoo Messenger breaking - but the longer-term benefit of the technology being introduced, such as being able to easily internationalize all applications, were huge.

But once they split the distro into RHEL and Fedora, they no longer had to maintain this balance. Now RHEL is constantly out of date - causing users to seek out third-party packages or compile things themselves, which defeats the whole purpose of stability. And Fedora is bleeding edge instead of cutting edge, making it painful and unpleasant to work with for anything but pure tinkering.

You saw similar user pain when Apple switched from OS 9 to OS X, or from PPC to x86. Users cried about this stuff - a LOT. (As with UTF8 on Linux, Adobe apps seemed to be one of the centerpoints of user pain.) But once the initial shock wore off - which was pretty quickly - everyone was a lot better off. Can you imagine what Apple's place in the technology industry would be today if they had stuck with OS 9 and PPC?

The curator role is surprisingly challenging to do right. I hope we can learn from the lessons of these companies, and others that curate successfully, as we continue to develop Heroku.

Video Quagmire

April 23, 2008 at 11:45 PM

2007 may have been the year of video on the internet, but support for video technology in software is still pretty poor. The emergence of Flash players enabled the video explosion, sure. But Flash is still proprietary and has a bunch of other problems as well, not the least of which is that it's not strictly a video format, but rather an entire programming environment which happens to support video.

Video is primarily such a mess because of codecs. I was first exposed to the codec madness circa 1999, when people in my office shared videos via a shared drive. I was using Linux exclusively (this was pre-OS X, remember), so this meant I could very rarely view them. I always assumed that OS 9 and Windows users didn't have these problems. In envisioned Mac and Windows users living in utopia of video, where they just clicked on any file and it opened and started playing.

Then I had occasion to use a friend's Windows computer to try to view video. Nope! Same codec problems. Then later I got a Mac. Bzzt! Some videos would play, others wouldn't. Windows, Mac, and Linux all had the same problem: fail to play the video, with an extremely unfriendly and unhelpful error dialog. (Not one of them said "You don't have the right codec." They all read something like, "Error code: -29")

Things are a bit better today. Actually I have no idea about Windows, but on Mac you can get a WMV plugin for Quicktime, and Ubuntu and other Linux distros prompt you to download reverse-engineered codecs from outside the US when you click on a video format that isn't recognized. Still, in neither case does it the video just play without any hassle. Linux is the easiest, but there's still a bunch of dialogs to click through. And this doesn't even begin to touch the problem of authoring: just look at the codec dropdown in iShowU:

How does one make an informed decision about this? I don't think most people do. I kept trying formats at random until I got one that 1. wasn't horribly grainy, 2. didn't produce massively large files, and 3. played on Quicktime and VLC without issues. This feels like the dark ages of digital video, not the revolution.

Ogg Theora could be the solution. It's a free and open standard, and could open up the creation and distribution of video in the same way that HTML did for documents.

As usual, though, the problem is default support. No one wants to install extra software to play video; but the two biggest operating system vendors (Microsoft and Apple) have their own proprietary formats (Windows Media and Quicktime) that they want to defend. So that's not going to happen. (Ubuntu plays Theora out of the box, I hardly need mention.)

At a recent Super Happy Dev House, I met someone who was working on Theora support for MediaWiki. He mentioned that Firefox 3 was going to support Ogg Theora out of the box, which I found very exciting. It would be as simple as a <video> tag in your html. Awesome.

Unfortunately, it looks like Ogg has been dropped from the latest HTML 5 specification, and from what I can tell FF3 is not going to have support for Theora (though it may offer the video tag, without any default codecs). Unawesome.

Still, all of this seems gives me some hope that there is a path out of this horrible quagmire that video technology is currently stuck in. We're not quite on the path yet, but at least it's there - waiting for when the world is ready for video stop sucking.

Comments: 4 (view/add your own) Tags: desktop, ux

The Startup Curve

April 23, 2008 at 11:08 PM

PG drew this on the whiteboard at the last dinner of our Y Combinator session:

So, so true.

Why No Love For RSpec?

April 22, 2008 at 08:11 PM

It's no secret that I'm a big RSpec fan. Test::Unit feels pretty outdated these days, and none of the other frameworks can yet match the level of BDD goodness you get from RSpec. Throw in that it's now a mature and stable library, and it seems like a sure bet for all your Ruby specing (or testing, if you like) needs.

It's thus surprising to me that some Rubyists seem reluctant to use RSpec. Certainly, some of this comes from the fact that it's not a standard include with Ruby or Rails, unlike Test::Unit. In this way it faces the same battle that Haml, DataMapper, Thin, or any other add-on library that swaps out a substantial component of the framework stack: the user must actively make the choice. Defaults are the status quo, the incumbent; they win, well, by default.

But I sense that people's mistrust of RSpec extends further than what these other components face. My guess is that the reasons for this are: too big, too complicated, and too much magic.

The first concern is a reasonable one - the plugins are pretty large, and especially since it's common to install it as a plugin rather than a gem, this can seem to bog down your source repo. The too big issue is a bit of an illusion, as Rick DeNatale explains.

The too complicated and too much magic problems can somewhat be addressed by using a subsest of the matcher library, as I suggested with minimalist RSpec matchers. It occurs to me that all of these problems could be solved with a lightweight implementation of RSpec which implements just the core syntax. That is:

describe MyClass do
  before do
    @my_obj = MyClass.new
  end

  it "sums two numbers" do
    MyClass.sum(1, 2).should == 3
  end

  it "raises an error when arguments are not integers" do
    lambda { MyClass.sum(1, 'x') }.should raise_error(ArgumentError)
  end
end

If someone wrote an leaner RSpec-alike library which ran the above spec correctly, I'd probably switch. (The example excludes RSpec's built-in specs and mocks, but I'd be ok using Mocha instead, which is very similar.) Maybe mSpec is such a thing, though I'm still kind of confused as to what it is exactly, since the readme claims you should still run the specs using RSpec.

A final reason why many people don't understand the importance of RSpec is simply not fully drinking the BDD koolaid. If you find yourself thinking things like "Well, yeah, BDD is a good idea, I hope to find the time to do it more often...", then I count you in that category.

I was in that position not too long ago, so don't feel bad. But it was using RSpec that caused the lightbulb to turn on above my head. Pat Maddox put it well in a mailing list post:

"I would say that TDD is a tool to help you solve the problem of designing and implementing behavior. Test::Unit works fine in that regard, but RSpec reduces the semantic distance between the developer and the problem domain."

The good news is, despite the sense of reluctance many display toward RSpec, it actually is catching on - even becoming the standard. Merb uses it by default out of the box. A recent Rails Envy podcast mentioned that their informal poll showed RSpec as the most popular testing/specing framework with 62% of the vote. (Test::Unit got around 25%, Shoulda around 12%.) The hosts expressed surprise at this. I was surprised too - pleasantly so.

But perhaps most important is that the Rubinius project uses RSpec, and has spawned a spinoff project for an executable specification of the Ruby language, which is being adopted most of the the major Ruby VM implementors (MRI/Yarv, JRuby, IronRuby, Rubinius). This means that soon the most important spec in the Ruby world - the spec for the very language itself - will use RSpec.

Ruby Conference Slides Online

April 18, 2008 at 03:50 PM

I've posted my slides from my talk rush, the Ruby shell and Unix Integration library, which I presented today at the Silicon Valley Ruby Conference.

Comments: 2 (view/add your own) Tags: events, rush

Model + Controller = Unified Resource?

April 16, 2008 at 12:05 PM

Harry Fuecks thinks MVC might be overrated. In a world of web resources, why not combine models and controllers together? Imagine replacing ActiveRecord (or my new favorite, DataMapper) with a server-side version of ActiveResource. GET, POST, PUT, and DELETE are filled in automatically, and you can extend their functionality and add suport methods.

He also argues that what we really want is RUD, not CRUD. The distinction between create and update is subtle, and hardly important if you think of resources as documents. (Document-oriented databases are poised to replace relational databases - we may soon be thinking in terms of documents instead of records even on the backend.) Think of your filesystem, the seminal document-oriented database: when you write a file, does it matter if one exists already? Not usually. File.open('test.txt', 'w') { |f| f.puts "hello" } behaves the same way regardless of the whether a file by that name previously existed or not.

This server-side ActiveResource might look something like:

class Post < Resource
  has_one :author
  has_many :comments, :dependent => :destroy

  def get
    super
  end

  def put
    super
  end

  def delete
    super
  end
end

It provides both the controller and the model. The superclass for each of the three public-facing methods handles writing it to the backend store; the relationships described by has_* give both the routing config and the database relationships.

This is more speculation than a real idea, but I found it to be an engaging thought experiment.

Comments: 3 (view/add your own) Tags: mvc, rest

Useful, Necessary, Beautiful

April 14, 2008 at 09:41 PM

The Shaker Design Philosophy, paraphrased nicely by Josh Porter:

Don't make something unless it is both necessary and useful, but if it is both necessary and useful, don't hesitate to make it beautiful.

Avoiding Inject

April 07, 2008 at 01:30 PM

I was rather taken with inject when I first started getting serious with Ruby. It allows you to turn ugly, imperative-style loops requiring temporary variables into functional-style expressions. Like this:

total = 0
items.each do |item|
  total += item.price * item.quantity
end
total

Becomes:

items.inject(0) do |total, item|
  total += item.price * item.quantity
end

Much better. (Jay Fields expands on this, in case you're not already an inject junkie.)

And yet, somehow, this hasn't always sat quite right with me. I had to look up the syntax quite a bit when I was first learning it (I always wanted to do |item, total| rather than the reverse), and from time to time my use of inject seems to create subtle bugs that take me a while to figure out. It feels right in theory, but in practice something is a little off.

My partner and coding buddy Orion pointed out to me recently that map is actually a simpler solution in most cases. The trick is knowing the right Enumerable methods to go with it. Like sum, perfect for the example above:

items.map { |item| item.price * item.quantity }.sum

This breaks the process into two steps: extracting the information you want, then operating on the result set. (I daresay this might be a simple version of map/reduce.) Plus, it works elegantly for hashes, something that always frustrates me about inject. For example, turning a hash into a key-value string with inject is:

hash.inject("") do |string, key_value|
        string += "#{key_value[0]}=#{key_value[1]}\n"
end

With map, this is:

params.map { |key, value| "#{key}=#{value}" }.join("\n")

The two-step process wins out on elegance here, too.

Comments: 5 (view/add your own) Tags: ruby

rest-client 0.4

April 05, 2008 at 12:59 PM

The fourth release of rest-client includes a patch from Greg Borenstein that makes it easy to send form-urlencoded data by passing a hash instead of a string as the payload:

RestClient.post 'http://myblog.example.com/posts',
    { 'posts[title]' => 'My Post', 'posts[body]' => 'Hello, world' }

Loose Whitespace Annoys Me

April 04, 2008 at 03:46 PM

It tickles me to death that Git highlights loose whitespace in red.

I may be showing my obsessive-compulsive side here, but one thing I don't like about TextMate is that it indents blank lines. (Other editors, such as vim and emacs, remove the superfluous whitespace when you press enter twice on an indented block. That is, they never save a file which has a blank line containing whitespace; blank lines are always just a newline and nothing else.)

I'd be ok with it if it was consistent, but it isn't. Which is why you end up with blank lines with whitespace that doesn't match nearby indents. Hardly a showstopper, but it does mean that I end up wasting time chasing whitespace around when I should be coding. (Britt Selvitelle agrees, and offers some tricks to work around TextMate's inherent whitespace sloppiness.) Maybe now that Git is all the rage, the TextMate author will be encouraged to change its handling of whitespace.

Update: You only get colorized diffs if you have this in your $HOME/.gitconfig:

[color]
    diff=auto
Comments: 4 (view/add your own) Tags: git, ux