Menu
Coddy logo textTech

to_s and inspect

Part of the Object Oriented Programming section of Coddy's Ruby journey. Lesson 5 of 57.

puts turns an object into text by calling its to_s method. The default to_s gives only the class name and a memory address, such as #<Book:0x000055d0>, so classes define their own. String interpolation calls to_s too:

class Book
  def initialize(title, pages)
    @title = title
    @pages = pages
  end

  def to_s
    "#{@title} (#{@pages} pages)"
  end
end

book = Book.new("Dune", 412)
puts book
puts "Reading #{book}"

Output:

Dune (412 pages)
Reading Dune (412 pages)

join also calls to_s on every element, so an array of your objects prints in your format:

class Book
  def initialize(title)
    @title = title
  end

  def to_s
    @title.upcase
  end
end

shelf = [Book.new("Dune"), Book.new("Emma")]
puts shelf.join(", ")
puts "Shelf: #{shelf.join(" / ")}"

Output:

DUNE, EMMA
Shelf: DUNE / EMMA

p is for programmers: it prints inspect, which shows a value unambiguously. A string keeps its quotes and nil is visible. For your own objects, the default inspect lists the instance variables:

p "Dune"
puts "Dune"
p [1, "a", nil]
puts [1, "a", nil].inspect

Output:

"Dune"
Dune
[1, "a", nil]
[1, "a", nil]

Override inspect to get a short, exact description for debugging. p and the inspect of an array then use it, while puts keeps using to_s:

class Point
  def initialize(x, y)
    @x = x
    @y = y
  end

  def to_s
    "(#{@x}, #{@y})"
  end

  def inspect
    "#<Point x=#{@x} y=#{@y}>"
  end
end

pt = Point.new(1, 2)
puts pt
p pt
p [pt, Point.new(0, 5)]

Output:

(1, 2)
#<Point x=1 y=2>
[#<Point x=1 y=2>, #<Point x=0 y=5>]
challenge icon

Challenge

Easy

Complete the class Track. initialize(title, artist, seconds) stores the values. to_s returns Dune by Ada (3:05), with the length as minutes and two-digit seconds, and inspect returns #<Track "Dune" 185s>, with the title in double quotes.

The supplied code reads tracks as title,artist,seconds lines, prints each with puts and then prints the whole list with p.

Your code goes in track.rb. main.rb holds the supplied input/output code and cannot be edited.

Try it yourself

require_relative 'track'

# Supplied input/output code: keep it as it is
input = []
while (line = gets)
  input << line.chomp
end
tracks = input.map do |line|
  title, artist, seconds = line.split(",")
  Track.new(title, artist, seconds.to_i)
end
tracks.each { |t| puts t }
p tracks
quiz iconTest yourself

This lesson includes a short quiz. Start the lesson to answer it and track your progress.

All lessons in Object Oriented Programming

Practice on your own: Online Ruby compiler