“A Little Ruby, a Lot of Objects,” back on line

When I was first learning Ruby, one of the resources that helped me most was Brian Marick’s “A Little Ruby, a Lot of Objects.” It’s modeled after The Little Schemer (or, if you’re older, The Little LISPer), but it uses Ruby, and teaches the core ideas of object-oriented programming in a way that helped me, even after I’d been doing OOP for 6 years. (I’m not surprised that his newer book, Functional Programming for the Object-Oriented Programmer, is just as illuminating.) The only thing I didn’t like was that it stopped after only 55 pages.

My team is about to welcome a new junior intern, and when Ben asked me for any learning resources I thought we should send, I suggested “A Little Ruby.” I have the original PDFs, but we were planning to send an email with URLs, and that’s when I realized that the book’s site, visibleworkings.com/little-ruby, was down.

I asked Brian whether I could host the files, and he agreed (thanks again!), so here they are:

A Little Ruby, A Lot of Objects

Front Matter

“My goal is to teach you a way to think about computation, to show you how far you can take a simple idea: that all computation consists of sending messages to objects.”

“The real reason for reading this book is that the ideas in it are neat.”

Chapter 1: We’ve Got Class…

The First Message: Computation is sending messages to objects.

The Second Message: Message names describe the desired result, independently of the object that provides it.

The Third Message: Classes provide interface and hide representation.

Chapter 2: …We Get It From Others

The Fourth Message: Protocols group messages into coherent sets. If two different classes implement the same protocol, programs that depend only on that protocol can use them interchangeably.

The Fifth Message: Classes define protocols for their subclasses.

The Sixth Message: If a class and its superclass have methods with the same name, the class’s methods take precedence.

The Seventh Message: Instance variables are always found in self.

Chapter 3: Turtles All The Way Down

The Eighth Message: Classes are objects with a protocol to create other objects

The Ninth Message: Methods are found by searching through lists of objects.

The Tenth Message: In computation, simple rules combine to allow complex possibilities

The Eleventh Message: Everything inherits from Object.

Ruby Scrubbing JavaScript: Raise Those Curly Braces

Of the Programmer Holy Wars, “curly braces on the same line, or the next line?” is not as vitriolic as emacs/vim or tabs/spaces, but it’s up there.

(Personally, I don’t care. I’ve done years with each style. You get used to it.)

In JavaScript, it’s less of an issue, because, when you put curly braces on the next line, JavaScript will (sometimes) automatically insert semicolons into your code. It’s well-documented and discussed, and understandable; here’s a question about it on stackoverflow.

Yesterday I reviewed some old JavaScript (circa 2007) that our web designer Daniel rehabilitated, and this concern came up. Rather than hunt around manually for dangling curly braces, I wrote some ruby to find and fix them.

# fix-js-curies.rb
ARGV.each do |filename|
  src = File.read(filename)

  # This multi-line regex looks for any { that
  # comes after a \n, and any tabs or spaces,
  # and replaces it with a space and a {.
  new_src = src.gsub(/\n[ \t]*\{/m, ' {')

  if src == new_src
    puts filename
  else
    puts "#{filename} fixed!"
    File.open(filename, 'w') do |f|
      f.puts new_src
    end
  end
end

You can pass it any .js files as command-line arguments:

$ ruby fix-js-curlies.rb app/assets/*.js

Props to Daniel: when I ran my script, it didn’t actually find any, because he got them all ahead of me.

Cantor’s Snowflake

The Koch snowflake is a famous fractal.

The Koch Snowflake fractal

So is the Cantor set.

The Cantor set

Less famous, maybe, is Cantor dust, a version of the Cantor set made with squares instead of lines, which apparently earned it a much cooler name.

But as far as I know, we have no Cantor snowflake.

Since it’s Christmas, and since, in the odd quiet moments between holiday noise, Daniel Shiffman’s Nature of Code has been keeping me company, I wondered if we could make a Cantor snowflake.

Here’s what I came up with.

cantor-snowflake

As a bonus, it contains the Koch snowflake inside of it! I didn’t expect that.

I also rendered a Cantor snowflake PDF, which has a couple extra generations. It could make a nice bookmark.

Here’s the sourcecode, which is also running on openprocessing:

void setup() {
  size(1450, 300);

  background(255);
  noStroke();
  fill(0);

  cantorSnowflake(0, height/2, 140, 280);
}

void cantorSnowflake(float x, float y, float length, float sideStep) {
  if (length < 0.1) return;

  pushMatrix();

  hexagon(x, y, length);

  translate(sideStep, 0);

  for (int i = 0; i < 6; i++) {
    PVector point = vector(i * THIRD_PI, length * 2 / 3);
    cantorSnowflake(point.x, point.y, length / 3, sideStep);
  }

  popMatrix();
}

void hexagon(float centerX, float centerY, float length) {
  translate(centerX, centerY);

  beginShape();
  for (int i = 0; i < 6; i++) {
    hexPoint(vector(i * THIRD_PI, length));
  }
  endShape(CLOSE);
}

void hexPoint(PVector v) {
  vertex(v.x, v.y);
}

PVector vector(float rads, float length) {
  return new PVector(cos(rads) * length, sin(rads) * length);
}

Happy Christmas!

ERMAHGERD, the Gem

I just published my first “official” gem, ermahgerd, and what an auspicious way start my gem-author career! ERMAHGERD, I’M A RERL RERBER PRERGRERMAHR!

It’s (currently) totally based on J Miller Design’s translator, but there are some bits I’d like to tweak. We’ll see, it’s just for fun.

Get started with ERMAHGERD:

$ gem install ermahgerd
$ irb
ruby-1.9.3-p0 :001 > require 'ermahgerd'
 => true 
ruby-1.9.3-p0 :002 > Ermahgerd.translate("Goosebumps, my favorite books!")
 => "GERSBERMS, MAH FRAVRIT BERKS!" 

Rails 3: Selectively Override Email Recipients

It’s a common thing, in your test environments, to intercept out-going email, and stuff it in some dumpster out back, so you don’t bother your users. We do this at SeeClickFix, and we’re upgrading to Rails 3, so I went searching for the new way to do this, and found Rob Aldred’s handy post on the subject.

So we deployed our Rails 3 branch to a test environment & unleashed our QA staff on it, but they all knew that they’d never get email from that environment, so they never checked for them. Which was a problem, because all the email were broken in QA. Oops.

It’d be nice to only dump certain messages (the ones to your normal users) and let through others (the ones to your QA staff). Can we do this? Let’s see.

ActionMailer::Base lets you register an interceptor, and every time it’s about to send an email, it’ll call your interceptor’s #delivering_email method with the email as an argument. All the examples I found register a class as an interceptor, with #delivering_email implemented as a class method, like this:

class FooInterceptor
  def self.delivering_email(message)
    message.to = "dump@example.com"
  end
end

ActionMailer::Base.register_interceptor(FooInterceptor)

Now that’s fine, but why pass a class with a class method? Why not an object with an instance method? Especially since a class is just an object, an instance of Class. Will ActionMailer::Base#register_interceptor do something funny with its argument? Try to call #new on it? Who knows?

I tried this just to see if it would work:

class FooBarRecipient
  def delivering_email(message)
    message.to = "dump@example.com"
  end
end

ActionMailer::Base.register_interceptor(FooBarRecipient.new)

And it does! Nice job, register_interceptor, not doing anything funky with it. Thanks!

This means we can create an interceptor object with a whitelist:

class WhitelistInterceptor

  def initialize(whitelist)
    @whitelist = whitelist
  end

  def delivering_email(message)
    message.to = Array(message.to).map { |address|
      if @whitelist.include?(address)
        address
      else
        "dump@example.com"
      end
    }
  end

end

Of course that’s really basic – you probably want to allow all email sent to your domain, for instance. And maybe you want the messages to be tagged somehow, so you can tell which test environment a message came from, so you give the WhitelistInterceptor the Rails environment to add as a message header. But that’s the idea. And my favorite part is that the class has no Rails dependencies, so it’s trivial to test.

Is there any reason not to do this?

Disable Your Links, or Gate Your Functions?

It’s pretty common to disable links and buttons that cause updates, so those updates don’t happen twice, and re-enable them when the update has finished.

At work, our app’s links are usually wired to javascript functions that use jQuery to scrape the form data and post it to web services via ajax. We normally disable links and buttons something like this:

var updateLink = $('#updateLink');  // Find the link.
updateLink.click(function() {       // When it's clicked...
   updateLink.disable();            // disable it...
   ajax({
      data: getFormData(),          // ... & send the form data
      url: 'http://someWebService', // to some web service.
      success: function(results) {  // When the service
         if (results.hasErrors) {   // finishes,
            showErrors(results);    // show any errors,
            updateLink.enable();    // and enable the link
         }                          // so they can try again.
      }
   });
});

We added those enable() and disable() functions to jQuery — they just add or remove the disabled attribute from whatever they’re called on. But it seems Firefox doesn’t support disabled on anchor tags, like IE8 does, so we couldn’t stop the repeat-calls that way.

We got to thinking, what if the link always called its javascript function, but the function could turn itself off after the first call, and back on after a successful ajax post? That led to this:

function makeGated(fn) {
   var open = true;
   var gate = {
      open: function() { open = true; }
      shut: function() { open = false; }
   };

   return function() {
      if (open) {
         fn(gate);
      }
   };
}

makeGated takes your function, and wraps it in another function, a gate function (it “makes your function a gated function”). When you call the function it creates, it will only call your function if the gate is open — which it is, at first. But then, your function can decide whether to close the gate (that’s why the gate is passed to your function). You could use it like this:

var updateLink = $('#updateLink');  // Find the link.
updateLink.click(
   makeGated(function(gate) {       // When it's clicked...
      gate.shut();                  // shut the gate...
      ajax({
         data: getFormData(),       // ...same as before...
         url: 'http://someWebService',
         success: function(results) {
            if (results.hasErrors) {
               showErrors(results);
               gate.open();  // Open the gate
                             // so they can try again.
            }
         }
      });
   }));

We dropped this in, and it worked pretty much as expected: you can click all you want, and the update will only fire once; when the update completes, it’ll turn back on.

The downside? Since it doesn’t disable the link, the user has no idea what’s going on. In fact, since the closed-gate function finishes so quickly, it seems like the button’s not doing anything at all, which might even make it look broken.

So we chucked it, and hid the links instead. It’s not as nifty, and it’s not reusable, but it’s clear enough for both end-users and programmers who don’t grok higher-order functions. Even when you have a nice, flexible language, and can make a sweet little hack, it doesn’t mean the dumb approach won’t sometimes win out.

Array.prototype.toString

This is one of my favorite javascript tricks, because of its effort-to-payoff ratio.

Problem: the default Array.prototype.toString hides any nested structure.

[1, 2, 3, 4, 5].toString(); //-> "1, 2, 3, 4, 5"
[1, 2, [3, 4], 5].toString(); //-> "1, 2, 3, 4, 5"

Solution: override Array.prototype.toString.

Array.prototype.toString = function() {
    return '[' + this.join(', ') + ']';
};

[1, 2, 3, 4, 5].toString(); //-> "[1, 2, 3, 4, 5]"
[1, 2, [3, 4], 5].toString(); //-> "[1, 2, [3, 4], 5]"

Firebug and Monaco, on Windows

I’ve been running Firebug at work for a long time, it’s a really solid tool. A while ago, I started using a Monaco.ttf for Windows. I think it looks much better on my Ubuntu system, but it’s nice to have on Vista.

Firebug was apparently written for the Mac, because it uses Monaco all over the place. That would be very nice, but on Windows, a bold Monaco is a wider Monaco.  This makes the line number gutters uneven, and makes the screen flash when you scroll through text:

I finally got irritated enough to google it, and I found this post by Thomas Scholz (it’s in German, here’s Google’s translation).

The details: Firebug’s CSS files are located in its extension directory, which is probably someplace like this:

  • Vista: C:\Users\{USERNAME}\AppData\Roaming\Mozilla\Firefox\Profiles\{alphanumerics}.default\extensions\firebug@software.joehewitt.com\skin\classic
  • XP: C:\Documents and Settings\{USERNAME}\Application Data\Mozilla Firefox\Profiles\extensions\firebug@software.joehewitt.com\skin\classic

Search-and-replace the Monaco away, and restart Firefox.

Clojure Changing My Mind

As good as Processing is, it’s still java. I’ve slowly been learning clojure, and trying to use it with Processing, via clj-processing. While the clojure docs and the book are both good, I’m still in that flounder-around stage, trying out tiny experiments to understand how things work.

I wanted a function to make saw-step sequences: (1 2 3 2 1 2 3 2 …). You give it the low bound, the high bound, and the step-size. For example:

  • (saw-step 1 4 1) gives (1 2 3 4 3 2 1 2 3 4 3 ...)
  • (saw-step 0 15 5) gives (0 5 10 15 10 5 0 5 ...)
  • (saw-step 0 5 2) gives (0 2 4 5 3 1 0 2 4 5 ...)

I’ve coded this kind of thing up in ruby, javascript, or java a dozen times, though it’s usually inside a loop, not returning a list. Something like this:

var min = 3;
var max = 7;
var step = 2;

var n = min;
while(shouldContinue()) {
    doSomethingWith(n);
    n += step;
    if (n+step > max || n-step < min) {
        step *= -1;  // turn around
    }
}

My first try in clojure took a similar tack. I never got it right, but it was something like this:

(defn saw-step
  [min max step-size]
    (let [step (ref step-size)]
      (iterate
       (fn [x]
         (if (or ( min (- x @step)))
           (dosync (alter step -)))
         (+ @step x))
         min)))

It’s a disaster — the parentheses don’t even match — but you get the gist. I was trying to cram the same imperative algorithm into clojure: keep some mutable state, add step to it, and when you reach the edges, mutate step to change direction. I kept getting bugs where it would go one step beyond the edge, or it would start working its way back from one edge, only to turn around again, and bounce against the edge forever.

I gave up and went to bed, but a few days later, I had better luck.

(defn saw-step
  [min max step]
     (cycle
      (into (vec (range min max step)) ; vec, so (into) adds to end
	    (for [x
		  (iterate #(- % step) max)
		  :while (> x min)] x))))

The first not-entirely-wrong step I made was to try breaking the list of numbers I wanted into two parts: the going-up numbers, and the coming-down numbers. (0 2 4 5 3 1) is just (0 2 4) + (5 3 1). The (range min max step) part gives you the going-ups, and the (for [x (iterate ...) stuff is the going-downs, as a list comprehension.

(One mistake I made was trying (range max min step) for the going-downs, which yields an empty list; another was using (iterate dec max), which never ends, because it keeps decrementing into the negatives. I found my way out with the list comprehension, but I bet there’s a better way.)

Once you have those two lists, you can use into to add each item from the second list to the first, giving you (0 2 4 5 3 1). That goes into cycle for a lazy, infinite sequence.

The solution’s not too bad: a saw-step is a cycle of the going-ups, followed by the going-downs. The code looks about that way.

(It occurred to me after that I could always use a default step of 1, and pipe the result through a scaling map. That would give me the bounds I wanted, with the extra benefit of evenly-spaced steps. Maybe I’ll remove step later.)

Alan Perlis said, “A language that doesn’t affect the way you think about programming, is not worth knowing.” He also said, “The only difference(!) between Shakespeare and you was the size of his idiom list – not the size of his vocabulary.”  Clojure’s changing my mind, a bit at a time.

A JavaScript War Story

What follows is an account from the author’s experience. Some details have been changed for the usual reasons, and a poor memory has fuzzed out the rest.

UPDATE: it turns out the technique described below is known as debouncing. What an awesome name!

My last job was for a company that made case-management software. With this software, you could track all kinds of data about your case: you could categorize it, sub-categorize it, say where and when it happened, note whether it was still open, track who was responsible…all kinds of stuff, great for data fiends.

One of our customers’ favorite features was the reports, and they were pretty spiffin’. But, not being ones to rest on our laurels, we were adding pivot-table reports, so you could count the number of cases, grouped by any criteria you wanted. The input screen let the customer pick their pivot criterion, and which criteria they wanted as columns, for sub-counts. We struggled to name these UI fields — something lucid, something explanatory, something evocative — something to make them understand what kind of report they were in for. After a while, we decided to just show them: when they changed their pivot criterion, we’d run some javascript to render a skeleton report, same as the real report, but minus the data. It would save them time, and save our servers.

The javascript was pretty involved. It had to generate the same HTML as we did for the pivot table, which meant it had to know (or make up) values for each criterion, like all the case categories and sub-categories, and which sub-categories belonged to which categories. And we let the customers pivot on up to THREE, count ‘em, different criteria. And it had to happen each time the user picked different pivot criteria. It took a few tricks, but we got it working. It ran slowly, maybe a few seconds, but it was quick enough, probably, especially once we threw in a little “please wait” spinner. Then we realized we needed to re-render whenever the window resized.

No biggie, I thought, and I quickly added window.onResize(reportPreview);. It worked great, except it re-rendered the report with every pixel-wide movement of the mouse, as the window was dragged to new widths and heights. Calling a function, one that runs for a few seconds, a hundred times in the time it took to widen the browser an inch, meant a locked browser. It meant “time to get more coffee,” and after, “time to fix the bug.”

I knew we could delay calling reportPreview, but we only wanted to delay it when the window was being resized — when the user changed the columns, there was no reason to wait. I was sure window.setTimeout() would do what we needed, but I didn’t want to muck up reportPreview() with it.

I’d been reading The Little Schemer lately, and noticing some striking similarities between javascript and scheme: first-class functions, and higher-order functions that take functions as arguments, and return other functions as values. It was fun reading, with its strange teacher-student dialog style. The material was better than brainteasers, and I knew it would make me a better programmer down the road, but I didn’t think of it as relevant to the day-job, as…applicable.

Then I realized higher-order functions were a way out of this. I could write a function, delay, that would wrap one long-running, slow-poke function in another function: an intermediary that you could call as many times a second as you wanted, but it would only call the slow-poke once things had settled down. delay would let us keep setTimeout out of reportPreview. Something like this:

function delay(millis, slowPoke) {
    var timeoutId = undefined;

    // This is the intermediary.  Call it lots, it won't hurt.
    return function() {
        if (timeoutId) {  // If we're waiting...
            clearTimeout(timeoutId); // re-start the clock.
        }
        timeoutId = window.setTimeout(slowPoke, millis);
    }
}

The first time you call the intermediary, it tells the window to call slowPoke after a bit, but every time you call it after that, it starts the clock over. It’s like when you’re in a five-minute time-out, and you start acting up after only three, so your mom says “Ok, buster, another five minutes.”

var fiveMinutes = 5 * 60 * 1000;
var screamAndShout = delay(fiveMinutes, function() {
    getBackToPlaying();
});

screamAndShout(); // Aw nuts, I'm in time-out.

// I'll be good for as long as I can, but...
screamAndShout(); // dang, five MORE minutes!

Once delay was in place, running reportPreview when the window was resized was no problem.

function reportPreview() {
    // recursion, DOM manipulation, insanity...
}
columnPicker.onChange(reportPreview);
window.onResize(delay(100, reportPreview));

After testing, we found that delaying it for 100 milliseconds made all the difference in the world.

Do you have a war story? Share it, and start the healing: tell a short one in the comments, or link to a longer one on your own damn blog.