A Night At the Movies 6/10 Problem with String vs Symbol


#1

Hello All,

The following code in the 6th exercise in “A Night at the Movies” gets the green check mark, but with testing, it never displays “Already in Library!” as it should when I type in “Jaws” or “Die_Hard” (adding a movie already in the library)

movies = {
  "Die_Hard" => 10,
  "Jaws" => 8
  }

puts "What would you like to do?
-- Type 'add' to add a movie.
-- Type 'update' to update a movie.
-- Type 'display' to display all movies.
-- Type 'delete' to delete a movie."

choice = gets.chomp

case choice

  when "add"
  puts "What's the title of the movie you want to add?"
  title = gets.chomp
  
  if movies[title.to_sym].nil?
     puts "How would you rate #{title}?"
     rating = gets.chomp
     movies[title.to_sym] = rating.to_i
 
  else
    puts "Already in the Library!"
  end
  
  movies[title.to_sym] = rating.to_i
  
  when "update"
  puts "Updated!"
  
  when "display"
  puts "Movies!"
  
  when "delete"
  puts "Deleted!"
  
else
  puts "Error!"
end

But, when I replace the initial hash with:

movies = {
Die_Hard: 10,
Jaws: 8
}

The “Already in Library!” else statement functions properly.
I understand that the previous has was in strings and the second is symbols.
My question is, how do I get the initial hash of strings ‘movies’ to change into symbols before the ‘case’?


#2
movies = {
  "Die_Hard" => 10,
  "Jaws" => 8
  }
temp = {}
movies.each_pair{|k,v| temp[k.to_sym] = v}
puts temp

Now we just need a way to replace movies with temp.


#3

Thanks @mtf,

I’m assuming this creates a new hash called temp filled with symbols. Does ‘.to_sym’ actually change the strings in movies to symbols or does it just create a new iteration of symbols?

I’m very new to Ruby and don’t understand how these things work yet.

And to address your final comment:

Would a .push work?


#4

I don’t believe so. .push is an array method. A hash needs to be updated, and has no order.

Search for a way to clone temp and assign it to movies so all the contents get swapped out. I’ll give it some more time a little later. I’ve got a meeting to attend.


Okay. I"m back, and the solution is actually simpler than I thought.

Hash#clone
movies = {
  "Die Hard" => 4.0,
  "Jaws" => 3.5
  }
temp = {}
movies.each_pair{|k,v| temp[k.to_sym] = v}
puts temp
movies = temp.clone
puts movies
title = "Motorcycle Diaries"
movies[title.to_sym] = 5.0
puts movies
puts temp
title = "Die Hard"
movies[title.to_sym] = 4.5
puts movies
puts temp
ruby 2.5.0p0 (2017-12-25 revision 61468) [x86_64-linux]
 >  
 {:"Die Hard"=>4.0, :Jaws=>3.5}
 {:"Die Hard"=>4.0, :Jaws=>3.5}
 {:"Die Hard"=>4.0, :Jaws=>3.5, :"Motorcycle Diaries"=>5.0}
 {:"Die Hard"=>4.0, :Jaws=>3.5}
 {:"Die Hard"=>4.5, :Jaws=>3.5, :"Motorcycle Diaries"=>5.0}
 {:"Die Hard"=>4.0, :Jaws=>3.5}
=> nil

Note how the two hashes are independent of each other. This means the temp hash can now be deleted.

temp = nil
puts movies
puts temp
{:"Die Hard"=>4.5, :Jaws=>3.5, :"Motorcycle Diaries"=>5.0}

=> nil

Now we have all the existing keys converted to symbols and can go on from here.

https://repl.it/@mtf/Convert-string-keys-to-symbols