In ruby I have created a class and array, to read the contents from a text file then output them.
class Album
attr_accessor :artist, :title, :genre, :tracks
album = Album.new(album_title, album_artist, album_genre, tracks)
-> tracks is an array of multiple lines read from the text file using a while loop. Context below, a_file/music_file File.new("album.txt", "r")
class Track
attr_accessor :name, :location
def read_track(a_file)
track_title = a_file.gets()
track_location = a_file.gets()
track = Track.new(track_title, track_location)
end
def read_tracks(music_file)
tracks = Array.new()
count = music_file.gets().to_i()
track = music_file
index = 0
while (index < count)
track = read_track(music_file)
tracks << track
index = 1
end
return tracks
end
after album = Album.new(album_title, album_artist, album_genre, tracks), I passed the album to a different procedure print_tracks(album), and in print_tracks(album), I have puts album.tracks
But instead of printing out several lines of track names and track locations, I get something that looks like this:
#<Track:0x000055c028027b08>
#<Track:0x000055c0280277c0>
#<Track:0x000055c028027630>
How do I print out the actual words on the file.
CodePudding user response:
What you are getting in return are instances of your Track class. Each of those instances has access to attributes like name and location as specified under the class definition in attr_accessor. You can change your last statement (return tracks
) (take note that return
here is not needed since its the last statement in the method, the last thing will be returned by default in ruby).
Try this instead of return tracks
tracks.map{ |track| {track_name: track.name, track_location: track.location} }
This was you will end up with array of hashes with keys of track_name and track_location each containing a value of one track. I am not sure what kind of format you want to return, but this is a rather simple, yet flexible. The most simplistic way would be array of array, which you can get using:
racks.map{ |track| [track.name, track.location] }
CodePudding user response:
You're observing the default behavior defined in Object#to_s
and Object#inspect
.
Ruby uses the to_s
method to convert objects to strings and the inspect
method to obtain string representations of objects suitable for debugging. By default, to_s
and inspect
are more or less the same thing. The only difference is inspect
will also show the instance variables.
You can and should override these methods in your Track
class. For example:
class Track
def to_s
"#{self.class.name} #{name} @ {location}"
end
def inspect
"#<#{to_s}>"
end
end
track.to_s
puts track
# Track: name @ /music/name.flac
track.inspect
p track
# #<Track: name @ /music/name.flac>