FAQ: Hashes and Symbols - Nil: a Formal Introduction

This community-built FAQ covers the “Nil: a Formal Introduction” exercise from the lesson “Hashes and Symbols”.

Paths and Courses
This exercise can be found in the following Codecademy content:

Learn Ruby

FAQs on the exercise Nil: a Formal Introduction

There are currently no frequently asked questions associated with this exercise – that’s where you come in! You can contribute to this section by offering your own questions, answers, or clarifications on this exercise. Ask or answer a question by clicking reply (reply) below.

If you’ve had an “aha” moment about the concepts, formatting, syntax, or anything else with this exercise, consider sharing those insights! Teaching others and answering their questions is one of the best ways to learn and stay sharp.

Join the Discussion. Help a fellow learner on their journey.

Ask or answer a question about this exercise by clicking reply (reply) below!

Agree with a comment or answer? Like (like) to up-vote the contribution!

Need broader help or resources? Head here.

Looking for motivation to keep learning? Join our wider discussions.

Learn more about how to use this guide.

Found a bug? Report it!

Have a question about your account or billing? Reach out to our customer support team!

None of the above? Find out where to ask other questions here!

creatures = Hash.new("No such creature!")
creatures = { "weasels" => 0,
  "puppies" => 6,
  "platypuses" => 3,
  "canaries" => 1,
  "Heffalumps" => 7,
  "Tiggers" => 1
}

puts creatures["puppies"]
puts creatures["Zoidberg"]

I expected it to print “No such creature!”, but it prints nothing on that.
Why doesn’t it work?

The first statement does not apply since a hash literal has been assigned to take its place.

We need to subscript to the hash without using assignment.

things = Hash.new('undefined')
puts things['stuff']
# <- undefined
1 Like

Thanks, now it’s clearer.

So to solve this issue on the second line we should use some merge or append (<<) rather than assignment?

2 Likes

Assignment is fine. When we polled the key, it was given the default value even though it was not added to the hash. This is more obvious if we use numbers.

puts stuff
# {}

histogram = Hash.new(0)
histogram['stuff'] += 1
puts histogram
# {"stuff" => 1}
1 Like

Thanks, mtf, I got this.

My question was more about how do I add a new keys and values, while keeping the default value in place.

I figured out that this way would work:

creatures = Hash.new("No such creature!")
creatures.merge!({ "weasels" => 0,
  "puppies" => 6,
  "platypuses" => 3,
  "canaries" => 1,
  "Heffalumps" => 7,
  "Tiggers" => 1
})

It doesn’t reset the default, and allows to add it all to the hash.

Maybe there’s a more elegant way to achieve the same goal?

There are in’s and out’s to every method, so before deciding which is elegant and which is not, be sure you are familiar with all the ramifications of a given method. For instance, Hash#merge will merge two hashes, but any keys that are duplicated will be altered to the have the merged value, not the original one. We would want to sort this out before merging else valuable data could be affected.

hsh[key] = value

is still a valid way to insert an item into the hash. The idea of default value (or nil) is to prevent errors from being thrown if we attempt to poll a key that does not exist.

While you’re investigating #merge, look into #store and see how that fits into to the picture.

1 Like

That’s reasonable. As you say, there may be a more direct approach and if you look through hash’s methods you’ll find it. (Ctrl+f is your friend here) https://docs.ruby-lang.org/en/2.5.0/Hash.html

When I use defaults for lookup tables it’s because there’s a valid value there which I haven’t set myself.
An example is if you’re counting things, adding 1 each time a thing is found. You’d use 0 as a default.
I don’t agree with using defaults as error handling.
But, obviously, in the interest of trying out how it works, it totally serves its purpose.

@mtf not sure what you mean about duplicate keys being altered. Entries with same keys will be overwritten, but that’s not surprising and no different from if updating them one at a time. (And it is known to be empty so it doesn’t happen anyway)

Is “nil” the literal output in the console? When I try to access a non-existent key I simply get no output in the console?

The only thing to output to the screen for puts nil will be the newline character. A lot of responses from completed code are 'nil', and yes in those instances the literal is what prints. nil is a primitive object with no attributes or methods, meaning no representation, beyond the coerced string we see in the console.

I am still confused actually here on when to expect to see nil or not.

accessing a non-existent key could sound like a response from a completed code which should show “nil” in console?

Accessing a non-existent key should raise an error.

Okay, I didn’t get anything when I tried it. Maybe a bug on the site. Thank you!

I don’t see anything after I submit the code either. Window remains black.

5 posts were split to a new topic: Nothing in the terminal window

is there any kind of contradiction between what they ask and the result ? They tell to ask for a key that does not exist and then I’m wrong because the key does not exist

3 Likes

Hello Caroline, and welcome to the community!

This isn’t obvious, but there’s no need to puts to the console in this case.

2 Likes

Thank you for answering ! I mean I looked at the solution and there is a “puts” as well.
(the first line of code with Hash.new, I added it to try but it didnt work as well without it)

Alright, that’s rather odd. When I try “View solution”, it gives me

creatures["birds"]

without puts


Anyways, keep on going! :slight_smile:

Can someone please explain following questions?

  1. why do we need this line -> creatures = Hash.new (“No such creature!”)?
  2. why nothing is printed in console when I called keys.