ruby

How to get a default value with hashes in ruby


I am trying to get a default value whilst using hashes in ruby. Looking up the documentation you use a fetch method. So if a hash is not entered then it defaults to a value. This is my code.

def input_students
  puts "Please enter the names and hobbies of the students plus country of    birth"
  puts "To finish, just hit return three times"

  #create the empty array
  students = []
  hobbies = []
  country = []
  cohort = []

  # Get the first name
  name = gets.chomp
  hobbies = gets.chomp
  country = gets.chomp
  cohort = gets.chomp

  while !name.empty? && !hobbies.empty? && !country.empty? && cohort.fetch(:cohort, january) do #This is to do with entering twice
    students << {name: name, hobbies: hobbies, country: country, cohort: cohort} #import part of the code.
    puts "Now we have #{students.count} students"

    # get another name from the user
    name = gets.chomp
    hobbies = gets.chomp
    country = gets.chomp
    cohort = gets.chomp
  end
  students
end

Solution

  • You just need to give fetch a default it can handle. It doesn't know what to do with january as you haven't declared any variable with that name. If you want to set the default value to the string "january", then you just need to quote it like this:

    cohort.fetch(:cohort, "january") 
    

    There are some decent examples in the documentation for fetch.

    Also, cohort isn't a Hash, it's a String since gets.chomp returns a String. fetch is for "fetching" values from a Hash. The way you're using it should be throwing an error similar to: undefined method 'fetch' for "whatever text you entered":String.

    Finally, since you're using it in a conditional, the result of your call to fetch is being evaluated for its truthiness. If you're setting a default, it will always be evaluated as true.

    If you just want to set a default for cohort if it's empty, you can just do something like this:

    cohort = gets.chomp
    cohort = "january" if cohort.empty?
    while !name.empty? && !hobbies.empty? && !country.empty?
      students << {
        name: name,
        hobbies: hobbies,
        country: country,
        cohort: cohort
      }
      ... # do more stuff
    

    Hope that's helpful.