Reputation:
I am new to Ruby and just had a quick question when writing a program that asks a user to create a playlist of their favorite songs!
class Playlist
array_songs = Array.new
print "How many songs do you want to add to your playlist? "
songs = gets.to_i
for i in 1..songs
print "Enter song #{i}: "
song = gets.chomp
print "Enter genre for song #{i}: "
genre = gets.chomp
print "Enter artist of song #{i}: "
artist = gets.to_i
p = playlist.new
p.set_song(song)
p.set_genre(genre)
p.set_artist(artist)
array_songs << p
end
end
puts "This is your current playlist: "
for song in array_songs
puts "#{song.get_song} #{song.get_genre} #{song.get_artist}"
end
So basically every time I run this, it won't work, saying I have undefined methods and such... Just want a few tips on how to make this work so that at the end of a user entering the songs, the result of all the songs will be printed! Thanks!
Upvotes: 0
Views: 1089
Reputation: 467
You appear to have a misunderstanding of what a class is, or at least, how to use them well.
A class is a type of object which represents a distinct concept or item in the internal universe of the application.
The internal universe of an application like Stack Overflow consists of (amongst other things) User
, Question
and Answer
objects. Therefore, these are some of the classes you might find in the source code.
An individual Answer
, like this one, or an individual User
, like you, is an instance of the class. It has its own distinct data, which is different to that of another User
or Answer
, but it shares the same behaviour, such as delete
or edit
.
You have a class called Playlist
. Logically, this should be a list of Song
s. As a Song
is a separate concept, with its own data and behaviour, it should be a separate class.
Because a Playlist
does not do anything at the moment, it's probably best to use an Array
object. So that you can change this in the future, you can do something like this:
Playlist = Array
And later:
class Playlist
# extra behaviour when needed
end
A Song
has three pieces of data:
name
genre
artist
In Ruby, we can use attr_accessor
to handle the setters and getters.
class Song
attr_accessor :name, :genre, :artist
end
Notice the case sensitivity on the class and variable names. You made that mistake with p = playlist.new
.
Here is the fully adapted version of the code. I have changed some of the variable names to improve readability.
I have also changed your for
loop to Ruby's .times
method, which I feel is easier to read.
Finally, I have changed the gets.to_i
for artist
to gets.chomp
, as I presumed it was supposed to be a String
like the others. Just change it back if I was wrong about this.
Playlist = Array
class Song
attr_accessor :name, :genre, :artist
end
songs = Playlist.new
print "How many songs do you want to add to your playlist? "
number_of_songs = gets.to_i
number_of_songs.times do |i|
song_number = i + 1
print "Enter song #{song_number}: "
name = gets.chomp
print "Enter genre for song #{song_number}: "
genre = gets.chomp
print "Enter artist of song #{song_number}: "
artist = gets.chomp
s = Song.new
s.name = name
s.genre = genre
s.artist = artist
songs << s
end
puts "This is your current playlist: "
songs.each do |song|
puts "#{song.name} #{song.genre} #{song.artist}"
end
Lastly, I know that this does not apply to your case, but I feel it is important to learn if you did not know already: you can use def
to add behaviour to a class. attr_accessor
does this implicitly.
class Duck
attr_accessor :name
def quack
"QUACK! My name is #{name}."
end
end
a_duck = Duck.new
a_duck.name = "Mr. Duck"
puts a_duck.quack
#=> QUACK! My name is Mr. Duck.
Good luck.
Upvotes: 2