to_s và inspect
Thuộc phần Lập trình hướng đối tượng trong hành trình Ruby của Coddy. Bài học 5 trên 57.
puts chuyển một đối tượng thành văn bản bằng cách gọi phương thức to_s của đối tượng đó. to_s mặc định chỉ trả về tên lớp và địa chỉ bộ nhớ, chẳng hạn như #<Book:0x000055d0>, nên các lớp tự định nghĩa phương thức này. Nội suy chuỗi cũng gọi to_s:
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}"Đầu ra:
Dune (412 pages)
Reading Dune (412 pages)join cũng gọi to_s trên từng phần tử, nên một mảng các đối tượng của bạn sẽ in ra theo định dạng bạn đã đặt:
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(" / ")}"Đầu ra:
DUNE, EMMA
Shelf: DUNE / EMMAp dành cho lập trình viên: nó in ra inspect, giúp hiển thị giá trị một cách rõ ràng. Chuỗi vẫn giữ dấu ngoặc kép và nil cũng hiện ra. Với các đối tượng của riêng bạn, inspect mặc định liệt kê các biến instance:
p "Dune"
puts "Dune"
p [1, "a", nil]
puts [1, "a", nil].inspectĐầu ra:
"Dune"
Dune
[1, "a", nil]
[1, "a", nil]Ghi đè inspect để có mô tả ngắn gọn, chính xác khi gỡ lỗi. p và inspect của mảng sẽ dùng mô tả này, còn puts vẫn dùng 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)]Đầu ra:
(1, 2)
#<Point x=1 y=2>
[#<Point x=1 y=2>, #<Point x=0 y=5>]Thử thách
DễHoàn thiện lớp Track. initialize(title, artist, seconds) lưu các giá trị. to_s trả về Dune by Ada (3:05), với thời lượng tính bằng phút và số giây gồm hai chữ số, còn inspect trả về #<Track "Dune" 185s>, với tiêu đề nằm trong dấu ngoặc kép.
Code được cung cấp đọc các bản nhạc từ những dòng có dạng title,artist,seconds, in ra từng bản nhạc bằng puts, sau đó in ra toàn bộ danh sách bằng p.
Code của bạn nằm trong track.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và bạn không thể chỉnh sửa tệp này.
Tự làm thử
require_relative 'track'
# Đoạn code đầu vào/đầu ra đã có sẵn: giữ nguyên
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
Bài học này có một bài trắc nghiệm ngắn. Bắt đầu bài học để trả lời và theo dõi tiến độ.
Tất cả bài học trong Lập trình hướng đối tượng
1Lớp và đối tượng
Làm việc với tệpĐịnh nghĩa lớpBiến instancePhương thức và selfto_s và inspectÔn tập: thẻ thư viện4Tính đóng gói
Phương thức riêng tưPhương thức được bảo vệPhương thức thiết lập riêng tưBảo vệ trạng tháiÔn tập: máy bán hàng tự động7Tính đa hình và duck typing
Tính đa hìnhDuck typingPhương thức trừu tượngcase và lớpÔn tập: phương thức thanh toán2Phương thức truy cập và self
Phương thức đọc và ghiPhương thức gán tùy chỉnhself trong phương thứcĐịnh danh và tính bằng nhauÔn tập: Danh sách liên hệTự luyện tập: Trình biên dịch Ruby online