Goeast
Goeast

Reputation: 71

Undefined method `<<' for nil:NilClass (NoMethodError)

I have an undefined method.

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

I do understand that @library[artist] gives nil, but I don't understand why and do not know how to fix it. Any advice?

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

Upvotes: 0

Views: 655

Answers (1)

Dave Schweisguth
Dave Schweisguth

Reputation: 37657

You're calling add_artist with one instance of Artist and add_song with another. When you look up the artist's list of songs in add_song with @library[artist] you're using a hash key (the second instance of Artist) which is not equivalent to the hash key under which you stored the list (the first instance of Artist), so you're not getting the list back, but nil.

To use two different instances of Artist as equivalent hash keys, you'll need to decide when two instances of Artist should be equal and implement eql? and hash appropriately.

Upvotes: 2

Related Questions