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 / EMMAp 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].inspectOutput:
"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
EasyComplete 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
This lesson includes a short quiz. Start the lesson to answer it and track your progress.
All lessons in Object Oriented Programming
1Classes and Objects
Working With FilesDefining ClassesInstance VariablesMethods and selfto_s and inspectRecap - Library Card7Polymorphism and Duck Typing
PolymorphismDuck TypingAbstract Methodscase and ClassesRecap - Payment Methods2Accessors and Self
Readers and WritersCustom Settersself in MethodsIdentity and EqualityRecap - Contact List8Special Methods
Equality and hashOperator MethodsIndexing and AppendingCustom CollectionsRecap - Fractions11Project: Library Management
Books and MembersBorrowing Books3Class Methods and Variables
Class MethodsClass Instance VariablesConstantsFactory MethodsRecap - Coupon CodesPractice on your own: Online Ruby compiler