Tuesday, January 31, 2012

Seven Languages in Seven Weeks: Ruby, Day 3

This is my 3rd day of Ruby in the Seven Languages in Seven Weeks series of posts. You can find the previous day here.

Ruby, Day 3: Thoughts

The third day combines metaprogramming techniques (define_methodmethod_missing, and mixins) with what what we learned in the previous chapters (flexible syntax, blocks, yield) to work some magic. Whereas day 1 and 2 showed how Ruby could be more concise and expressive than other languages, this chapter shows some of the capabilities available in Ruby, such as beautiful DSLs and composable designs, that are nearly impossible in stricter languages.

I saw small of examples of this when I was working on the Resume Builder: the profile data I was fetching from the LinkedIn APIs came back as JSON. I wanted to have a nice Ruby class to wrap the JSON data and was able to do this cleanly and concisely using some very simple metaprogramming:

Instead of defining dozens of getters and setters as in the LinkedIn API Java Library, I just declared the fields in an array (SIMPLE_PROFILE_FIELDS), looped over them, and used define_method to create the appropriate methods. To be fair, this is kids stuff; if you really want to see metaprogramming shine, take a gander over at ActiveRecord.

Of course, with great power comes great big bullet wounds in the foot. Metaprogramming must be used with more a bit more caution than other programming techniques, as chasing down errors in dynamic methods and trying to discern "magic" can be painful.

Ruby, Day 3: Problems

CSV application

There was only one problem to solve on this day: modify the CSV application (see the original code here and the original output here) to return a CsvRow object. Use method_missing on that CsvRow to return the value for the column given a heading.

Using this sample file:

The code above will produce the following output:

Moving on

This was the final day in the Ruby chapter. Join me next time as I work my way through a totally new language: Io.

Monday, January 30, 2012

Sherlock, The Reichenbach Fall: What Really Happened?

The PBS/BBC Sherlock series is one of the most entertaining shows I've seen in years. It's a modern take on Conan Doyle's classic with strong writing, a superb cast, and plenty of mystery and deduction. If you're not watching it, you're really missing out.

Spoiler alert!

In fact, if you're not watching it, you should probably miss out on this blog post too. Seriously, stop reading.

What follows is an in-depth, full-of-spoilers discussion of what happens in the final episode of the show thus far, The Reichenbach Fall.

The final question

I'm sure you know exactly what I'm going to discuss: how did Sherlock fake his own death?

Using my amateur deductive reasoning and a healthy amount of rewind & pause, I have a pretty good guess at what happened. Let me walk you through the reasoning.

To start with, let's state the very obvious: either the body that fell off the roof was (a) Sherlock, or (b) it wasn't. I think we can fairly confidently eliminate option (b).

An impostor?

Could Sherlock have thrown Moriarty's body or the test dummy from earlier in the episode in his place? Not likely.

First, there was no way Sherlock could have bent over, hauled up a body or a dummy, brought it to the edge, and shoved it over, all without Watson noticing. There were some quick cuts and edits during the scenen, but we have no reason to believe that Watson looked away from Sherlock at any point during their conversation.

Other practicalities make this even more difficult: Moriarty was dressed noticeably differently than Sherlock (different coat, white shirt instead of dark, a tie instead of a scarf) and had shorter hair; seconds before Sherlock jumps, he looks back and Moriarty's body is lying there, still in the original outfit; the scene where Sherlock jumps is shot from behind and it's clear no one is just shoving a body/dummy off the roof.

Finally, the biggest evidence of all: the body falling through the air is clearly flailing its arms and legs. Neither a dummy nor a dead body would fall like that.

Verdict: it must have been Sherlock himself who jumped off the building.

How did he survive?

One key piece of evidence is that Sherlock is extremely specific in where he wants Watson to stand during their conversation. Here is the layout of the scene:

When Watson arrives, Sherlock is on the hospital roof, some 6-8 stories up, with a shorter, 2-3 story brick building between him and Watson. Watson tries to run around to the side of the brick building, but Sherlock yells at him to return to his previous spot. Sherlock is very vehement about this.

It's likely that Watson would be able to see Sherlock from either vantage point, which leaves only one other possibility for why Sherlock would care about where Watson stands:
(1) There was something between the brick building and the hospital that Sherlock didn't want Watson to see.
After Sherlock jumps, Watson again tries to run around the brick building and this time, is knocked down by someone on a bike. This is unlikely to be an accident and gives us our second hint:
(2) Sherlock needed to delay Watson until the something was no longer visible.
If you watch the scene closely, there is one item that fits both of these criteria: a truck filled with bags (garbage? recycling? laundry?) parked right next to the spot where Sherlock's body ends up. You get your first glimpse of this truck just as Watson is coming around the corner, just before he is knocked down:

You see the same truck drive away, out of the scene, a few seconds later as Watson finally gets to Holmes' body:

Think on that for a second: if a body comes crashing down a few feet from your truck, do you just casually drive away or jump out and see what the hell just happened? The fact that the truck drove away increases our confidence that it was part of the plot.

Verdict: the bags in the back of the truck served as padding to break Sherlocks' fall.

How did it go down?

Before meeting with Moriarty, Holmes seeks out Molly and tells her that he thinks he will die and that he needs her help. Holmes must've already realized that Moriarty's goal was to get him to commit suicide, so he enlisted Molly - who works at a morgue and could certainly fake autopsy reports and death certificates - to help him fake it. It's also worth remembering that it was Sherlock, not Moriarty, who arranged the meeting on, of all places, the rooftop of a hospital.

When Moriarty blew his brains out, Sherlock had no choice, and jumped. He landed in the truck, covered himself with some sort of blood (possibly provided by Molly), and dropped down onto the pavement to play dead. In fact, he did better than that. We saw Holmes with a bouncy ball much of the episode; it turns out there is a classic magic trick that involves squeezing a ball under your armpit to cut off circulation to your arm and make it seem like you have no heartbeat.

What about the bystanders?

Since all the bystanders could see the truck and Holmes fall into it, they must have been in on it. The crowd that gathers around Holmes' body and the biker that knocks over Watson were either part of Holmes' homeless network or government folks brought in by Mycroft.

Mycroft is an interesting possibility because his reaction to reading about Holmes' death is ambiguous: was he sad or relieved? Even more telling is the fact that Mycroft isn't with Watson and Mrs. Hudson at the cemetery to pay his respects to Holmes. My guess is that Mycroft knows Sherlock is alive, though it's possible that he merely deduced it after the fact.

No matter how improbable..

It'll be some time before the third season comes out and reveals the truth. In the meantime, feel free to join me in speculating by leaving your best theory in the comments.

Sunday, January 29, 2012

Seven Languages in Seven Weeks: Ruby, Day 2

In my previous post, I went through the Day 1 Ruby problems from Seven Languages in Seven Weeks. Today, I'll share my solutions to the Day 2 problems and some more thoughts about Ruby.

Ruby, Day 2: Thoughts

I originally learned Ruby (and many other programming languages) the "hacker way": that is, I did a 10 minute syntax tutorial, browsed other peoples' code a bit, and then just started using the language, looking up missing pieces as I went. Although this is the most fun and productive way I've found to get started with a language, it can also lead to missing some of the finer points and subtleties.

For example, until the "Ruby, Day 2" chapter, I never had a full appreciation for Ruby code blocks and the yield keyword. For example, even though I frequently used "times" to do looping, I never thought deeply about how it worked:

It turns out that times is just a function (slightly obscured because Ruby doesn't require parentheses for function calls) on the Integer class that takes a code block as an argument. Times could be implemented as follows:

This style of coding allows for some powerful possibilities. For example, it is surprisingly easy to introduce a "do in a transaction" function:

Using this, I can now trivially wrap any number of statements in a transaction:

The equivalent in less expressive languages, such as Java, often involves vastly more code, implementing arbitrary interfaces, anonymous inner classes, and a lot of very hard-to-read code. For comparison, here is an example of how Java's Spring Framework recommends wrapping JDBC code in transactions:

Ruby, Day 2: Problems

The Day 2 problems are only slightly tougher than Day 1. The most fun part was coming up with a way to keep the code as concise as possible.

Print 16
Print the contents of an Array of 16 numbers, 4 numbers at a time, using just "each". Now, do the same with "each_slice" in Enumerable.

Modify the Tree class initializer (original code here) so it can accept a nested structure of Hashes. Trickiest part here was that the "collect" function can call the passed in block with either one argument that's an Array or two arguments that represent the (key, value) pair.

Write a simple grep that will print the lines and line numbers of a file having any occurrence of a phrase anywhere in that line.

Ruby vs. Java, Round 2

I couldn't resist implementing the grep code in Java to see how it compares:

It's 33 lines long. The Ruby solution was a one-liner.

Ruby, Continued

Check out more Ruby goodness on Ruby, Day 3.

Seven Languages in Seven Weeks: Ruby, Day 1

I recently picked up a copy of Seven Languages in Seven Weeks by Bruce A Tate. The book is a survey of seven very different programming languages: Ruby, IO, Prolog, Scala, Erlang, Clojure, and Haskell. For each language, the goal is to give you just enough of a taste that you can see what makes it unique, what its strengths and weaknesses are, and the mindset and philosophy behind it.

Each section of the book focuses on a different language and includes coding problems for the reader to try at home. I've decided to record my my solutions to the problems and thoughts about each language in my blog. Today, we'll start with Ruby.

Ruby, Day 1: Thoughts

I've used Ruby fairly extensively the last few years, including several Ruby on Rails apps (Resume Builder, Veterans Hackday) and a number of utility scripts. There is a lot to like about Ruby - the concise & clean syntax, incredible flexibility, expressiveness, powerful DSLs - but my favorite part is the central tennet of the language, as expressed by its creator:
"Ruby is designed to make programmers happy." Yukihiro Matsumoto
The language isn't built for speed, concurrency, or any particular feature set. Its central "success metric" is programmer happiness and productivity, which are, arguably, the biggest bottlenecks in most projects.

Ruby, Day 1: Problems

The "Day 1" Ruby chapter focused on the very basics of the language, so I didn't learn anything new. The problems are extremely simple and basic, but for completeness, here are my solutions:

Hello, World
Print the string "Hello, world".

Hello, Ruby
For the String "Hello, Ruby", find the index of the word "Ruby".

Print Name
Print your name ten times.

Print Sentence
Print the string "This is sentence number 1" where the number 1 changes from 1 to 10.

Random Number
Write a program that picks a random number. Let a player guess the number, telling the player whether the guess is too high or too low.

Ruby vs. Java

Coming from a Java background, every time I see Ruby, I'm amazed at how concise and readable it is. There is far less boilerplate: you don't have to wrap everything in classes and methods, no semi-colons, far fewer curly braces, and so on. Everything is an object and there are countless helper functions, all with intuitive names: even if you've never used Ruby, it's easy to guess the effects of 10.times or 1.upto(10). Whereas in the Java world, libraries seem to compete on having every bell, whistle, and tuning knob, in the Ruby world, libraries focus much more on having the simplest, easiest, one-line-and-you're-done API possible.

For comparison, I implemented the number guessing game in Java:

It's has more than twice the number of lines of code as the Ruby version (and I kept opening curly braces on the same line!) and even though I've been doing Java for a very long time, it still took longer to write. Of course, there are many other trade-offs at play here, but they key thing to think about is the golden rule of programming:
"Programs must be written for people to read, and only incidentally for machines to execute.SICP
Ruby has its downsides, but it is one of the best languages I've seen for writing code that others can read, understand, and maintain for a long time after.

Ruby, Continued

The Ruby explorations continue on Ruby, Day 2.