Learn the Zen of a Programming Language with Koans

I love the idea behind Ruby Koans: write a set of failing unit tests that teach you about the essence of ruby as make every test turn green. It's a brilliant idea. The tests themselves are usually simple and illustrative. You even get encouragement (or enlightenment? :-) as you fix them.

The good news is that this idea has spread beyond ruby. There are koans in many languages:


While learning a programming language is best achieved by writing a useful application, these koans are a very welcome (and fun!) addition.

Rails3 Custom Password Validators

As I was writing validators for the User class of a Rails 3 app, I wanted to make sure that people wouldn't use their names, usernames, or email addresses as passwords.
Unfortunately I couldn't find a way to accomplish this with the built-in validators. Fortunately Rails 3 makes it easy to write your own custom validators.

Here's an extract of my User class

The "password => true" tells Rails to call my custom validator which, in this case, has to be called password_format.rb.

I keep my custom validators in /lib/validators, so I need to add the following to my config/application.rb file:

And finally the validator itself:

(Don't forget to write the specs to test this! :-)

Fusing RSS feeds together from Posterous and other blogs

Posterous is a great web app: they've managed to the keep it simple and elegant to use while making it ever more sophisticated (thanks in large part to Garry Tan's leadership).

They're also very quick to respond to questions from users:

Why did I need such a script? My oldest domain, cyberclip.com, was registered in 1995 (back when "cyber" was cool! ;-) and went through early years of excitement and later years of neglect. A few months ago I streamlined it to a very simple design:

Recently I thought it would be nice to add just a little more content and decided to include a list of the newest posts from all my blogs. Since Posterous doesn't supply a consolidated feed, here's the ruby script I wrote to generate one. I've only tested it with FeedBurner and Posterous but it should work with all properly formatted RSS feeds.

I've purposely kept error handling out of this script for simplicity's sake because that's handled by the program that invokes it. That prog runs as a cron job and regens the homepage on a regular basis. It won't replace the homepage if RSSFusion errors out for whatever reason. So worst case is a stale homepage, not a broken one.

Combining blog posts for inclusion in another page is one use, but this script could also be used to generate a fused RSS feed of multiple blogs, which is something I should probably add to my homepage as well...

Optimizing Facebook's "Hoppity" Puzzle

I found Facebook's puzzle page the other day. While it has some very meaty challenges, it also has a couple of trivial ones. These easy puzzles are there to allow you to make sure you can submit solutions (I'm not consistently getting mine to run but I'm hopeful that turning off "Always send Windows-friendly attachments" in OSX Mail will do the trick).

One easy puzzle is called Hoppity. Essential you count up from 1 to a specified number and follow these rules
  • For integers that are evenly divisible by three, output the exact string Hoppity, followed by a newline.
  • For integers that are evenly divisible by five, output the exact string Hophop, followed by a newline.
  • For integers that are evenly divisble by both three and five, do not do any of the above, but instead output the exact string Hop, followed by a newline.
This very simple program is typically written with a few if then else's, though you could also simulate a bitmask and use a case statement:

As soon as I'd written it I started wondering: can I optimize this? I mean, this is Facebook we're talking about. Endless scale. So if they offered a Hoppity function on the main page, you bet they'd have to make it run fast! :-)

Looking at this program it's clear that the output should repeat every 15 counts. Here's a Mathematica plot to illustrate this where I've replaced Hoppity, Hophop, and Hop with 1, 2, and 3 respectively.

So if you're ever interviewing at Facebook and you're given this problem (which would be surprising, I agree), you can offer this optimization to make sure the Hoppity feature doesn't take down their servers when they release it to all their members :-)

Pre-computing is always useful!

No More Excuses! Using RVM to Play with Rails 3

Now that Rails 3.0 is out, it's high time to start using it. But what if you want to keep Rails 2.x around for your current projects? Fortunately, on OS X, there's a simple solution: RVM.

Once you've installed RVM, you'll need to install a version of ruby compatible with Rails 3. There are two choices: 1.8.7 and 1.9.2. Given its new features and speed improvements, 1.9.2 is the one to choose, unless you have particular dependencies on 1.8.7.

Installing 1.9.2 is simple: rvm install 1.9.2. This will download, compile, and install 1.9.2 to a .rvm folder in your home directory.

Once that's done, type rvm 1.9.2 to switch over and rvm info to confirm that you're now running 1.9.2. Note: this will only apply to the current terminal window, here's how to make it the default.

Type gem list and you should see just two gems: rake and bundler.

Now go ahead and install Rails 3: gem install rails. Confirm by way of rails --version and gem list.

That's it, you're done... Now have fun!

What to go back to your previous version of ruby? Just type: rvm system and you'll revert back to your standard ruby installation and the gems that went with it.

RailsConf 2006

I attended RailsConf in Chicago about 10 days ago. It was a great way to find out what was happening in arguably the most vibrant part of the web development community. I met a lot of people over those three days and would always ask them: "So, are you doing rails by day, by night, or both?". Most of the answers were "by night", with a few "just starting by day", and one "both". From my unstatistical sample, it seems like rails clearly had people's mindshare but getting it into their "workshare" is a different story.

A quick search on google or technorati will turn up a lot of info on the conference. Here are some of my favorite moments (in no particular order):

  • Martin Fowler's keynote: he spoke for over an hour about ruby, rails, frameworks & their (dis)advantages, etc. All pretty much ad lib. I have a number of his books and it was great hearing him speak live. Very interesting.
  • Why the lucky stiff's concert / monologue / animations extraordinaire. A glance at his site will tell you that all is not as it should be in Why's brain, which made his concert that much more fun.
  • Mike Clark's intro to Capistrano. This is the utility I really want to play with.
  • Justin Gehtland's overview of Ajax and RJS with Rails, and esp. the sneak peak at the new version of scaffolding he and his colleagues are working on called Streamlined.
  • One of the pleasures of attending a conference is discovering great new speakers. Out of the railsconf crew, my pick goes to Matt Biddulph. Matt's presentation was not only engaging, enlightening, and full of cool annecdotes but also focused on a BBC-related project. Having grown up in London, the beeb is still near and dear to my heart. I've found lots of interesting topics on Matt's blog, such as this great example of putting the Wikipedia and Yahoo APIs to use. Cheers Matt!
  • DHH's keynote started off with me thinking "CRUD? Why is he talking to us about CRUD?" and ended with the thoughts "Wow! This is a cool way of looking at things, must try it out!".
  • Last but not least, hooking up with a long lost friend and, as it turns out, rails and OSX fan Steve Chanin.

Next year's conference is in Portland and will be co-organized by O'Reilly. They're clearly pursuing rails as strong alpha (and dare I say beta?) geek territory. Lots of fun in store!

IRB Anywhere

IRB, short for Interactive RuBy, is a very useful ruby shell. Just run "irb" and you'll end up in a interactive ruby session. This comes in very handy for running various snippets of code to make sure they do what you intend. But what if you want to run IRB in the middle of a running program, so you can interact with it?

Turns out this is very simple:

#irbtest.rb

require 'irb'

some_var = 1
SOME_CONST = "hello"
puts "before irb"

IRB.start

puts "after irb"
puts some_var
puts SOME_CONST

The Smallest Proxy?

I needed an http proxy for another project (more on that later) and thought it would be fun to write one in ruby. How simple can it be? With a few compromises, it can be very short indeed:

I'm cheating in a couple places. I'm only handling GET requests, and I'm using Hiroshi Nakamura's excellent http-access2 package.

On the other hand, it's multi-threaded and it handles redirects, a must for the web.

SQL Server Adapter Fixed (sort of)

Many thanks to Ryan Tomayko for fixing the MS SQL adapter bug I posted a little while back.

Things aren't all roses, as Ryan states:

Quick Note: the SQL parsing regexp stuff in this adapter is bound to fail in many edge cases. This patch improves the accuracy of the regexen in many places but the basic parsing logic is flawed and could probably use a complete overhaul that accounted for things like habtm and eager loading issues from the beginning.

But it's still cool to see the process working and bugs getting fixed Cheers Ryan!

Reasons to Love Ruby

Bruce Tate's article on alternatives to Java mentions many of the aspects of ruby that I'm growing to love.

It wouldn't make sense to repeat them all here, others have stated ruby's strengths far better than I.

However, I would recommend giving ruby a shot. I gave this language a cursory look a couple years ago, after seeing a /. posting. At the time I thought "Hmmm... it just looks like a slightly better scripting language".

In some ways I feel I was right, ruby offers evolutionary improvements over other languages. But in many ways I was wrong, because the sum of all its improvements make ruby stand out compared to its peers.

What I like the most about ruby is its intuitiveness. Whenever I learn a new programming language, I always feel that I'm stumbling around at first, stringing together keywords thinking "I bet this won't work" because I haven't internalized the language's ideosyncrasies yet.

Well, in ruby I'm finding to my surprise that my bets are wrong, things do work the way I think they should. A language that intuitively makes sense is worth cherishing.

Here are some resources to get people started: