Передача Ruby Hash в классы

Я столкнулся с проблемой учебной тренировки, и я не мог понять это. Вот ссылка на упражнение. https://learnrubythehardway.org/book/ex40.html

Ниже представлены мои работы. В учебном упражнении 2 я передал переменные, и это сработало. Однако на третьем учебном упражнении я нарушил свой код. Я понял, что передаю не переменную, а хеш. И поскольку мой класс принимает 2 аргумента, я не мог понять, как передать словарь как 2 аргумента.

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)

Вот вывод. Что он должен сделать, так это вернуть певца/группу и вернуть запрошенную строку текста.

Я новичок в кодинге, посоветуйте, как передать хеши в классы? Как передать хешlovingThis в Song.new() и прочитать как 2 аргумента?


person Joey    schedule 23.04.2017    source источник
comment
Ваша лирика ivar должна быть массивом? Если это так, вы можете создать хэш-переменную, где ключом является 'singer_name', а значением является массив лирических строк. При переходе к классу используйте: Song.new(some_hash['singer_name'], some_hash.keys.first).   -  person Anton    schedule 23.04.2017


Ответы (1)


вы можете передать хэш конструктору класса так же, как мы передаем любую другую переменную, но для этого вам нужно изменить определение конструктора, чтобы принимать переменное количество аргументов, т.е. 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)
person aqfaridi    schedule 23.04.2017
comment
Большое спасибо, я никогда не думал об изменении количества принимаемых аргументов. Я пытался получить 2 аргумента, изменив хэш или создав функции, которые возвращают 2 аргумента. Это работает отлично! - person Joey; 23.04.2017