Joey
Joey

Reputation: 13

Passing Ruby Hash into Classes

I ran into a study drill problem, and I couldn't figure it out. Here's the link to the exercise. https://learnrubythehardway.org/book/ex40.html

Below are my work. On Study Drill 2, I passed in variables and it worked. However, at study drill 3, I broke my code. I realized I wasn't passing in variable, but a hash. And because my class takes in 2 arguments, I couldn't figure out how to pass a dictionary as 2 arguments.

class Song

  def initialize(lyrics, singer)
    @lyrics = lyrics
    @singer = singer
  end

  def sing_along()
    @lyrics.each {|line| puts line}
  end

    def singer_name()
    puts "The song is composed by #{@singer}"
  end

  def line_reader(lineNum)
    line = @lyrics[lineNum-1]
    puts "The lyrics line #{lineNum} is \"#{line}\"."
  end

end

# The lyrics are arrays, so they have [] brackets
practiceSing = Song.new(["This is line 1",
              "This is line 2",
              "This is line 3"],"PracticeBand")

practiceSing.sing_along()
practiceSing.singer_name()
practiceSing.line_reader(3)

puts "." * 20
puts "\n"

# Variable for passing. Working on dictionary to pass the singer value.
lovingThis = {["Don't know if I'm right",
              "but let's see if this works",
              "I hope it does"] => 'TestingBand'}

# Everything after this line is somewhat bugged
# Because I was using a variable as an argument
# I couldn't figure out how to use dictionary or function to work with 
this

practiceVariable = Song.new(lovingThis,lovingThis)

practiceVariable.sing_along()
practiceVariable.singer_name()
practiceVariable.line_reader(3)

Here's the Output. What it should do is return the singer/band, and return requested lyrics line.

I'm new to coding, please advise how to pass hashes into classes? How to pass lovingThis hash into Song.new() and read as 2 arguments?

Upvotes: 1

Views: 1314

Answers (1)

aqfaridi
aqfaridi

Reputation: 739

you can pass hash to constructor of class in the same way as we pass any other variable, But for that you need to change your constructor definition to take variable number of arguments i.e def initialize(*args)

class Song
  def initialize(*args)
    if args[0].instance_of? Hash
      @lyrics = args[0].keys.first
      @singer = args[0].values.first
    else
      @lyrics = args[0]
      @singer = args[1]
    end
  end

  def sing_along()
    @lyrics.each {|line| puts line}
  end

  def singer_name()
    puts "The song is composed by #{@singer}"
  end

  def line_reader(lineNum)
    line = @lyrics[lineNum-1]
    puts "The lyrics line #{lineNum} is \"#{line}\"."
  end
end

# The lyrics are arrays, so they have [] brackets
practiceSing = Song.new(["This is line 1",
              "This is line 2",
              "This is line 3"],"PracticeBand")

practiceSing.sing_along()
practiceSing.singer_name()
practiceSing.line_reader(3)

puts "." * 20
puts "\n"

# Variable for passing. Working on dictionary to pass the singer value.
lovingThis = {["Don't know if I'm right",
              "but let's see if this works",
              "I hope it does"] => 'TestingBand'}

practiceVariable = Song.new(lovingThis)

practiceVariable.sing_along()
practiceVariable.singer_name()
practiceVariable.line_reader(3)

Upvotes: 1

Related Questions