An introduction to hashes

If you’re somewhat familiar with ruby, there are good chances that you won’t learn anything new and exciting in this article. However, if you’re new to the language or just didn’t have time to take a look at ruby hashes yet, maybe you should continue reading.

What is a hash ?

A hash is a collection of objects, exactly like an array. The difference with arrays though, is that the indexes of a hash are not represented with integer values (FixNum instances). Instead, the key can be an object of any type! This means that instead of accessing your hash this way : result = my_hash[4], you can access it this way : result = my_hash[‘the_thing_im_looking_for’] or, to do things in a more rubyish manner : result = my_hash[:the_thing_im_looking_for]. To create a new hash from scratch, you just have to specify the various key/value pairs and separates them with the hash literal “=>” :

animals = { :dog => "charlie", :cat => "kwiki", :mouse => "squeaky" }

Why should I use hashes ?

One of the obvious advantages with hashes is their readability. When you write animals[4], it’s quite hard to see which animal you are trying to get. When you write animals[:dog], it becomes pretty obvious. A maybe less obvious but extremely useful thing about hashes is that you can improve the way you pass parameters to your methods by making them more flexible. When you use this technique, the order of the parameters becomes totally irrelevant! Ruby helps you along the way to achieve this. Let’s see how :
First : let’s take a look at the method call

dance_like_an_idiot(:frequency => "every minute",
			   :idiocy_level => "REALLY idiot",
			   :risk => "losing credibility forever")

Now, let’s take a look at that dance_like_an_idiot method

def dance_like_an_idiot(params)
  puts(params[:frequency]) # writes "every minute"
  puts(params[:idiocy_level]) # writes "REALLY idiot"
  puts(params[:risk]) # writes "losing credibility forever"
  #instructions to start the idiotic dance
end

The first thing you’ll notice is that even though you passed 3 parameters to the method, that method accepted just one. What is going on here? Well, you know ruby is your friend and that a friend is always there to help you, right? Well, in that case you won’t be surprised to learn that it did something really cool for you in the background. The other thing you will notice is that we passed our parameters in an unusual way to our method. For each parameter, we specified a key/value pair separated by the “=>” literal. If you remember, it looks really similar to the way we created our hash from scratch earlier in this article. In fact, that’s exactly what happened. The one difference is that we didn’t assign the key/value pairs to an object. The twist is exactly there : Ruby did it for you (I told you he was your friend). Ruby created an “anonymous” hash on the fly with the key/value pairs you specified when calling the dance_like_an_idiot method. The new created hash then has been passed to the params parameter at the receiving end. From there, the dance_like_an_idiot method was able to use the hash in any way it wanted to.
The great thing about this technique is that you don’t have to care about the order in which you pass your parameters to a method because those parameters will get merged into a single hash anyway. You can even omit to specify a key/value pair and the method will still be called (if the method tries to use an item in the hash that hasn’t been specified by the caller, it will in fact be dealing with a nil object (external link)).
You can also pass both standard parameters and a hash to a method. However, if you do so, the order in which you pass those parameters will become important.
For example :

#given the following method declaration :
def dance_like_an_idiot(normal_parameter1,normal_parameter2,params)
  puts(normal_parameter1)
  puts(normal_parameter2)
  puts(params[:frequency])
  puts(params[:idiocy_level])
  puts(params[:risk])
  #instructions to start the idiotic dance
end
#you could write :
dance_like_an_idiot("bleh","blah",:risk=>"be considered as a moron")
#but you couldn't write :
dance_like_an_idiot(:risk=>"getting beat down","bleh","blah")

Hashes do not replace arrays

Even though a hash is more flexible than an array, it must be noted that since the hash keys are not numerical values (FixNum instances), it cannot be ordered as easily. The other disadvantage is that it is less performant than arrays for the same reason. Still, ruby hashes are extremely useful. Most of the time you will prefer a hash to an array for the added flexibility.

3 thoughts on “An introduction to hashes

Leave a Reply

Your email address will not be published. Required fields are marked *