Hashes - Learn Ruby The Beginner Guide An Introduction to Ruby Programming (2015)

Learn Ruby The Beginner Guide An Introduction to Ruby Programming (2015)

Hashes

Hashes are similar to arrays. A key difference is that arrays use integers (0, 1, 2,...) for indexing, while a hash can use other object types.

The implicit form is written like this:

age = {"Gilbert" => 25, "Tammy" => 32}

The hash name is age. The hash holds two keys and two associated values. Gilbert is the key for the value 25. Notice that we didn't use a simple equals symbol to set our keys equal to our values. We used what's called a hash rocket. Hash rockets are easy to remember because they look like a rocket. Look at it: => It's beautiful.

We access the values the same way we would with an array. The difference is we use the key name instead of an index number.

puts age["Gilbert"]

25

When you create a hash you're not required to immediately populate it. You can simply create a hash and then add keys and values to them later. You could do it this way:

potatoes = {}

But we're going to do it this way instead:

potatoes = Hash.new

An empty hash called potatoes is created. Now we will add stuff to it.

potatoes["breakfast"] = "hash browns"

potatoes["lunch"] = "fries"

potatoes["dinner"] = "mashed"

print potatoes

{"breakfast"=>"hash browns", "lunch"=>"fries", "dinner"=>"mashed"}

That was fun. Practice makes better. Do it again using the alternate = {} syntax, and then fill it with user data.

users = {}

puts "What is your name?"

name = gets.chomp

puts "What is your age?"

age = gets.chomp.to_i

users[name] = age

print users

What is your name?

Jake

What is your age?

27

{"Jake"=>27}

You might've noticed that we added a to_i in there. The reason for that is because the user input will return as a string otherwise. We want it to return as an integer. That's what the to_i method will do for us.

The to_i method is an easy to remember mnemonic. It means to integer. It should be easy to extrapolate on what to_s means. Yep, to string.

Symbols as Hash Keys

Recall our discussion on Strings vs. Symbols. Remember that symbols have one instance. Whereas strings can have multiple instances. Because of this, we can optimize our programs performance by using symbols as our keys rather than strings. Going forward we will use symbols rather than strings as our hash keys. It will look like this:

person_profile = { :name => "Tim", :age => 23, :gender => "M" }

Optimizing Hash Syntax

Ruby is meant to be a programmer's best friend. You might wonder why creating multiple ways of doing things is beneficial. Well, the best argument is that that's how human language works. There are many ways to write a sentence. A sentence can be written multiple ways. Language also works towards condensing syntax:

TIL = Today I Learned.

TLDR = Too Long Didn't Read.

WTF = What The Fun (Wait, that's not right. WTF Jake?)

Because Ruby seeks both optimization and expressiveness, multiple syntaxes have emerged. Since we're using symbols as our keys in hashes, we can leave out the hashrocket by swapping our colon to the tail of our symbol name:

person_profile = {name: "Time", age: 23, gender: "M"}

This hash takes less keystrokes to make than the prior one.

Why teach alternative syntaxes at all?

If you're new to programming you may be wondering why I've taught you alternate syntaxes to begin with. The answer lies in understanding legacy code when you're presented with it. Ruby is still relatively new compared to other programming languages. In fact, it was heavily influenced by Perl, Smalltalk, Eiffel, Ada, and Lisp. However, Ruby has been around long enough that there's plenty of job opportunities in maintaining and updating code. Further, many online tutorials and older forum posts use these syntaxes interchangeably. It's my job to proactively teach you the different modalities that you'll encounter.

Default Values in Hashes

When we call a key that doesn't exist, the default return is nil. What can we do when we don't want the value nil to be returned? We can set a default value. First, create a hash that will return nil when we check if anything is in it.

user = Hash.new #Our hash exists. It's just empty.

puts user[:birthday]

Nil

We want to add substance to our return. Let's create a default value. Add the string "No such key." in parentheses on the tail of our hash.

user = Hash.new("No such key.")

puts user[:birthday]

No such key.