Lost in Translation?

Ruby Hashes vs. JavaScript Objects

Posted by 'Tine Zekis on May 24, 2015 · 6 mins read

Assignment: Technical Blog | JavaScript

This week at Dev Bootcamp, we started learning a new language: JavaScript. There are many similarities between JavaScript and Ruby, as well as many important differences. As with the study of any two languages, it is important to understand which pieces can be translated literally, and which pieces run the risk of getting lost in translation. In order to explore some of these further, we will focus on just one concept in each language. In this post, we will discuss Ruby Hashes and JavaScript Objects.

Ruby Hashes

In Ruby, a hash is a data-storage class. It is similar to an array in that it can store multiple items. However, unlike in the array, the order of these items is unimportant. This means that we do not reference items within a hash by their ordinal location. Instead, all items in a hash are arranged into key/value pairs. Each key points to a corresponding value. For example, if I wanted to keep track of abbreviations for elements of the periodic table, I could create a hash. Each element would be a key with its corresponding abbreviation as the value:

periodic_abbrevs = {"Hydrogen" => "H", "Oxygen" => "O", "Carbon" => "C", "Zinc" => "Zn",
  "Gold" => "Au", "Copper" => "Cu", "Magnesium" => "Mg"}
For all you science buffs out there, you have probably noticed that the elements in this hash are not presented in order according to the periodic table. This does not matter, as for our purposes, we will only need to access an abbreviation (value) by it's element name (key), not by where it falls on the table of elements. If we want to print to the console the abbreviation for Gold, we can do so thusly:
puts periodic_abbrevs["Gold"]
=> Au
You have probably also noticed that our hash is not exhaustive. There are still many more elements in the periodic table. Fortunately, we can easily add or remove key/value pairs to a hash. If we want our hash to include phosphorus, for instance, here's how we add it:
periodic_abbrevs["Phosphorus"] = "P"
=> {"Hydrogen" => "H", "Oxygen" => "O", "Carbon" => "C", "Zinc" => "Zn", "Gold" => "Au",
     "Copper" => "Cu", "Magnesium" => "Mg", "Phosphorus" => "P"}

A hash is like an algebraic function in that multiple keys may point to equivalent values, but a single key cannot point to more than one value. In other words, each input must have only one output. To give another example, let's say that we are keeping track of the ages of children at a daycare. The following hash would work just fine:

ages = {sarah: 3, johnny: 4, mary: 4, andy: 3, henry: 4, sally: 3}
It is perfectly alright for several of these children to be the same age; their name keys can point to equivalent values. However, we cannot have one name point to two different ages:
ages = {sarah: 3, sarah: 4, johnny: 4 ... etc.} # unacceptable hash
If there are really two Sarahs at this daycare, then they must have different names for their keys. Perhaps sarah_jones and sarah_smith. Otherwise, how can the program know which value to access for that key? Please note that if you add an existing key to a hash, it will overwrite the existing key/value pair, replacing the previous value with the new one.

JavaScript Objects

In JavaScript, an object is a wrapped collection of properties. Perhaps we have several musicians which each have a name, instrument, and genre. We would store this information into various Musician objects thusly:

function Musician(name, instrument, genre) {
  this.name = name;
  this.instrument = instrument;
  this.genre = genre;
}
var yoYoMa = new Musician("Yo-Yo Ma", "cello", "Classical")
Later, if I need to access the instrument Yo-Yo Ma plays, I can simply call for his instrument property:
yoYoMa.instrument;
=> cello
Additionally, I can add and remove properties from an object. For instance, we can add a famous Yo-Yo Ma quote to the yoYoMa object thusly:
yoYoMa.quote = "I think one of the great things about being a musician
  is that you never stop learning."

Key Points for Translation

As you have likely noticed, hashes in Ruby and objects in JavaScript have many similarities. The properties of an object have names and associated values, much like the key/value pairs of a hash. We can access these values at any time by referencing their names or keys. We can also add and remove properties or key/value pairs. So, if I were translating a hash from Ruby into JavaScript, I would likely use an object. But be careful, because these two things are not identical!

First, as we have seen from our examples, we do not construct these things in the same way in the two languages. The syntax is quite different. Additionally, Ruby and JavaScript have multiple ways to create and build onto hashes and objects, respectively. Trying to use the syntax of one in the other language would create several errors.

Another word of caution has to do with the English language. In Ruby, there are also such things as objects, and they can be quite different from hashes. In fact, a hash is just one type of infinitely many objects in Ruby, since we can invent our own classes to create new types of objects all the time. So, while it is important to note these similarities for ease of understanding, we must not be too quick to equate them.