Ruby & (Ampersand) Parameter Demystified

Idea

Recently I was asked a question about ‘& parameters’ when you define and/or call methods which take a block e.g.:

def blah(&block)
  yadda(block)
end

def yadda(block)
  foo(&block)
end

def foo(&block)
  block.call
end

blah do
  puts "hello"
end

As you pass this parameter around, sometimes the ampersand appears in front of it, but other times it doesn’t, seemingly with no rhyme of reason. As we dig into crazy metaprogramming or write various libraries, it is often hard to remember how confusing Ruby can be when you’re starting out. So, let’s dig into this a little more deeply and shed some light on what’s going on.

The Implicit Block

Methods in Ruby can take arguments in all sorts of interesting ways. One case that’s especially interesting is when a Ruby method takes a block.

In fact, all Ruby methods can implicitly take a block, without needing to specify this in the parameter list or having to use the block within the method body e.g.:

def hello
end

hello do
  puts "hello"
end

This will execute without any trouble but nothing will be printed out as we’re not executing the block that we’re passing in. We can – of course – easily execute the block by yielding to it:

Ruby – Why U No Have Nested Exceptions?

Why U No

One of the things we almost always do these days when we write our libraries and apps, is use other libraries. Inevitably something will go wrong with those libraries and exceptions will be produced. Sometimes these are expected (e.g. an HTTP client that produces an exception when you encounter a 500 response or a connection timeout), sometimes they are unexpected. Either way you don’t want to allow the exceptions from these external libraries to bubble up through your code and potentially crash your application or cause other weirdness. Especially considering that many of these exceptions will be custom types from the libraries you’re using. No-one wants strange exceptions percolating through their code.

What you want to do, is ensure that all interactions with these external libraries are wrapped in a begin..rescue..end. You catch all external errors and can now decide how to handle them. You can throw your hands up in the air and just re-raise the same error:

begin
  SomeExternalLibrary.do_stuff
rescue => e
  raise
end

This doesn’t really win us anything. Better yet you would raise one of your own custom error types.

The Best Way To Pretty Print JSON On The Command-Line

Print

Developers tend to work with APIs a lot and these days most of these APIs are JSON. These JSON strings aren’t exactly easy to read unless they are formatted well. There are many services online that can pretty print JSON for you, but that’s annoying. I love the command-line and whenever I am playing with new APIs or writing my own I mostly use CURL which means I need a good way to pretty print my JSON on the command-line. It should be simple, quick, easy to remember, easy to install – we’re not trying to solve complex algorithms, just format some JSON.

The ‘Good’ Old Faithful

One way that is always available is the Python JSON tool. So you can always do this:

echo '{"b":2, "a":1}' | python -mjson.tool

Which will give you:

{
    "a": 1,
    "b": 2
}

This is alright and, as I said, it is always available. However note that it has sorted our keys which is a major disadvantage. It is also a bit of a handful to write when you just want to pretty print some JSON. I only ever use this when I am on an unfamiliar computer and there is nothing better.

I Was Nominated To Speak At LoneStarRuby Conference 2013

A few days ago I woke up to see this in my Twitter stream:

Looking at the list of nominated speakers, I am in extremely illustrious company which was just amazing to see. Of course I replied with my appreciation. Then a little later I saw this:

Which was also very nice.

Who would have thought something like this would ever happen – thanks @IndianGuru.

Anyway, if LoneStarRuby Conference 2013 is of any interest to you and you’d like to make me write a talk hear me speak, you can go and vote.

A Closure Is Not Always A Closure In Ruby

Surprise

Often you don’t really think about what particular language features mean, until those features come and bite you. For me one such feature was Ruby’s instance_eval. We all know how instance_eval works, it’s pretty straight forward. We pass it a block, and that block gets executed in the context of the object on which we call instance_eval e.g.:

a = Object.new
a.instance_eval do
  def hello
    puts "hello"
  end
end
a.hello

The object a will get a hello method and the subsequent a.hello call will succeed. So what’s the gotcha?

The one overwhelming use of instance_eval is for creating configuration DSLs. I won’t go into that right now – it deserves a post of its own. Suffice to say that when used for this purpose, the closure semantics of the block that you pass to instance_eval don’t matter, i.e. you don’t tend to use the variables (or call methods) from the scope where the block was created. If you do need to use the variables or methods from the scope where the block was created, you might be in for a rude surprise.

What Is A Startup (Or A Startup Idea)?

Pirate

Is a startup all about the idea? Is it a bunch of people hacking together? It is not quite a company in the traditional sense of the word (at least not yet). I like to think of a startup as a series of assumptions. Your startup idea is just one assumption or alternatively there are many assumptions inherent in your idea. Let's take a simple one we're all familiar with:

"People want to connect with their friends online"

The main assumption is that people actually DO want to connect with their friends online (of course we know now that they do, but a few years ago it wasn't so obvious). Some of the inherent assumptions might be:

  • People want to know what their friends are doing right now
  • People want to see interesting links from their friends
  • We have a way to acquire users in the initial stages
  • People will want to let their friends know about our service
  • People will want to pay for our service
  • etc.

Why Developers Never Use State Machines

A few months ago I saw a great little blog post about state machines on the Shopify blog. The message was that state machines are great and developers should use them more – given my recent experiences with state machines at CrowdHired, I could certainly agree with that. But it got me thinking, how many times in my developer career have I actually used a state machine (either separate library or even hand-rolled abstraction)? The answer is zero times – which surprised the hell out of me since state machines really are very useful. So I decided to engage in a bit of introspection and figure out why we tend to manage our "state" and "status" fields in an ad-hoc fashion rather than doing what is clearly called for.

We Don't Need One Until We Do

The problem is that you almost never create an object fully formed with all the behaviour it is ever going to need, rather you build it up over time. The same is true for the "states" that a state machine candidate object can be in. So, early on you don't feel like your objects' state machine behaviour is complex enough to warrant a "full-blown" state machine (YAGNI and all that jazz), but later on – when it IS complex enough – you feel like you've invested too much time/effort to replace it with something that has equivalent functionality. It's a bit of a catch-22. It's overkill and by the time it's not, it's too late.

When Developers Go To Great Length To Save Typing 4 Letters

Great Lengths

Heroku is a great platform. Long before I joined and when I say long, I mean in startup terms (i.e. a few weeks before I joined :)) – the decision was made that CrowdHired would be hosted on Heroku. Shortly after I came on board, Heroku released their new Cedar stack and we quickly migrated across to that. I find it kinda amusing that we're currently in alpha, deploying to a platform that's in beta. Latest and greatest FTW. While migrating to the new stack we also settled on Thin as our web server. The Cedar stack allows you to use whatever web server you want in production and will run on Webrick by default – not ideal. Since we were going to use Thin in production it made sense that we'd also use it in development instead of Webrick.

When you're using Rails, swapping a new web server in is pretty painless. Just include the gem and then use the rails s command to launch your new server e.g

Even Boring Form Data Can Be Interesting (For A Developer)

Bored

What could be more boring than capturing credit card data on a form? Well, it's actually not that boring since you may want to encrypt this particular data, which presents it's own set of challenges. Nevertheless, it's still a textbox which takes digits that you store in a database – whoopty doo – not exactly rocket surgery. Well, I've got a piece of data that's got the credit card beat for sheer mundanity – the ABN. If you're an Australian you know all about this. For everybody else, it stands for Australian Business Number which is an 11 digit number, provided by the government to every company. It's not secret (you can look them up online), so you don't even need to encrypt it – difficult to get excited about that. Of course if that was the end of the story, this wouldn't be much of a blog post, so – as you might imagine – things are not as bland as they appear.

Algorithms, A Dropbox Challenge And Dynamic Programming

AlgorithmLately I've slowly been trying to grok the fullness of dynamic programming. It is an algorithmic technique that the vast majority of developers never master, which is unfortunate since it can help you come up with viable solutions for seemingly intractable problems. The issue with dynamic programming (besides the totally misleading name), is that it can be very difficult to see how to apply it to a particular problem and even when you do, it is a real pain to get it right. Anyway, I don't want to expound on this, I have something more interesting in mind.

The Dropbox Challenges

I was surfing the web the other day and in the course of my random wanderings I ended up at the Dropbox programming challenges page. Apparently, the Dropbox guys have posted up some coding challenges for people who want to apply to work there (and everyone else, I guess, since it's on the internet and all :)). Challenge 3 (The Dropbox Diet) immediately caught my eye since it looked like one of those problems that should have a dynamic programming solution, so I decided to use it as an opportunity to practice. The full description of the problem is on the challenge page, but here is the gist of it.