2016-05-27 3 views
0

У меня есть неопределенный метод.Неопределенный метод `<< 'для nil: NilClass (NoMethodError)

rb:31:in `add_song': undefined method `<<' for nil:NilClass (NoMethodError) 

Я понимаю, что @library[artist] дает nil, но я не понимаю, почему и не знаю, как это исправить. Любой совет?

module Promptable 
    def prompt(message = "What music would you like to add", symbol = ":>") 
    print message 
    print symbol 
    gets.chomp 
    end 
end 


class Library 
    attr_accessor :artist, :song 
    def initialize 
    @library = {} 
    end 

    def add_artist(artist) 
    @library[artist] = [] 
    end 

    def add_song(song) 
    @library[artist] << song 
    end 

    def show 
    puts @library 
    end 
end 

class Artist 
    attr_accessor :name, :song 

    def initialize(artist) 
    @name = artist[:name] 
    @song = artist[:song] 
    end 

    def to_s 
    "#{name}, #{song}" 
    end 
end 


if __FILE__ == $PROGRAM_NAME 
    include Promptable 
    include Menu 
    my_library = Library.new 
    my_library.add_artist(Artist.new(:name => prompt("What it the artist name ?"))) 
    my_library.add_song(Artist.new(:song => prompt("What is the song name ?"))) 
    my_library.show 
end 

ответ

2

Вы звоните add_artist с одним экземпляром Artist и add_song с другой. Когда вы просматриваете список песен исполнителя в add_song с помощью @library[artist], вы используете хэш-ключ (второй экземпляр Artist), который не эквивалентен хэш-ключу, под которым вы сохранили список (первый экземпляр Artist), поэтому вы не получите список обратно, но nil.

Чтобы использовать два разных экземпляра Artist в качестве эквивалентных хеш-ключей, вам нужно будет решить, когда два экземпляра Artist должны быть равны и implement eql? and hash appropriately.

Смежные вопросы