In this section, we will learn how to use blocks with Hashes.
Note: we’re assuming you’re already familiar with Ruby Hashes and Blocks.
Ruby Hashes with Default Blocks
In the Ruby Hashes and default value section, we mentioned that a hash object will return the value nil if we call a key in a hash object and that object didn’t have the specified key. Also we mentioned that we can change this default value to something other than the value nil so that whenever we call a key in the object and it didn’t have that, our default value will return instead.
The problem that the default value is trying to solve is that it gives you a more readable and understandable value whenever you want to get a key that does not exist! But what if you want to automatically add the specified key (the one that the target hash object didn’t have at the moment) to the hash object and set a default value for it then?
Well, Ruby has the answer for this and that’s using a default block for a hash object!
Basically, when you set a default block for a hash object, that will be called whenever you want to call for a key in a hash object, but the object doesn’t have the specified key.
So now in the default block you have this ability to add that key (the one that was called on the object) and set a default value for it as well.
Alright, let’s see the syntax of the default blocks and then we will continue our discussion on the way they work in Ruby.
Ruby Hash with Default Blocks Syntax:
holder = Hash.new do |hash, key| #instructions… end
As you can see, right after the `new` method, we’ve passed a block that has two parameters:
The first parameter is a reference to the hash object that is created as a result of calling the `new` method.
The second parameter is called `key` and that’s the key that we pass to the hash object when we want to get its value, but the key doesn’t exist in the target hash object!
So now whenever we call the hash object with a key that doesn’t exist in the target hash object, this block will be executed and a reference to the hash object and the specified key will be passed as the argument of this block.
Note: only for those keys that don’t exist in the specified hash object, the block will run!
Now with this block, we can take a key that didn’t exist in the hash object and add it to the object with a default value if needed.
Example: adding a block to a Ruby Hash object
person = Hash.new do |hash, key| hash[key] = "This is a default value" end person[:name] person[:last_name] person[:age] puts person.to_s
Output:
{:name=>"This is a default value", :last_name=>"This is a default value", :age=>"This is a default value"}
As you can see, the hash object we created here didn’t have any key in it. But then when we called the hash with keys that didn’t exist in its body, the default block ran for them and these keys are now added to the hash with a default value then. (Because we’ve set the body of the default block to add those keys with a default value).