Home > Back-end >  Ruby how to print/puts read file contents instead of a bunch of numbers/symbols
Ruby how to print/puts read file contents instead of a bunch of numbers/symbols

Time:10-20

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>
  • Related