Bộ sưu tập tùy chỉnh
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 40 trên 57.
Một lớp tập hợp kết hợp một số phương thức đặc biệt: each với Enumerable, << để thêm phần tử, size, và to_s cùng inspect để in ra. each cũng nên hoạt động khi không có khối lệnh, bằng cách trả về một bộ liệt kê với to_enum, giống như mảng:
class TodoList
include Enumerable
def initialize
@items = []
end
def <<(item)
@items << item
self
end
def each
return to_enum(:each) unless block_given?
@items.each { |item| yield item }
self
end
end
list = TodoList.new << "wash" << "shop" << "cook"
list.each.with_index(1) { |item, n| puts "#{n}. #{item}" }
p list.select { |i| i.include?("o") }Đầu ra:
1. wash
2. shop
3. cook
["shop", "cook"]block_given? cho biết bên gọi có truyền một khối lệnh hay không. Enumerator được trả về khi không có khối lệnh hỗ trợ nối chuỗi, chẳng hạn như each.with_index, each_slice hoặc next:
class Countdown
include Enumerable
def initialize(from)
@from = from
end
def each
return to_enum(:each) unless block_given?
@from.downto(1) { |n| yield n }
end
end
e = Countdown.new(3).each
puts e.next
puts e.next
p Countdown.new(5).each_slice(2).to_aĐầu ra:
3
2
[[5, 4], [3, 2], [1]]to_s là văn bản thân thiện dành cho người dùng, còn inspect là phần tóm tắt ngắn dành cho lập trình viên. Với một tập hợp, inspect thường hiển thị lớp và kích thước thay vì từng phần tử:
class TodoList
include Enumerable
def initialize(*items)
@items = items
end
def each(&block)
@items.each(&block)
end
def size
@items.size
end
def to_s
map.with_index(1) { |item, n| "#{n}. #{item}" }.join("\n")
end
def inspect
"#<TodoList #{size} items>"
end
end
list = TodoList.new("wash", "shop")
puts list
p listĐầu ra:
1. wash
2. shop
#<TodoList 2 mục>Enumerable cung cấp count, nhưng không cung cấp size, empty?, << hoặc []: những phương thức đó thuộc về lớp, vì chỉ lớp mới biết các phần tử được lưu trữ như thế nào. Định nghĩa chúng giúp bộ sưu tập hoạt động như một mảng đối với nơi gọi chúng:
def size
@items.size
end
def empty?
@items.empty?
end
def [](index)
@items[index]
endThử thách
DễHoàn thiện lớp TodoList. << thêm nội dung của một công việc và trả về danh sách. each lần lượt đưa ra các công việc và trả về to_enum(:each) nếu không có khối lệnh. Bao gồm Enumerable. size trả về số lượng công việc. to_s trả về các công việc dưới dạng những dòng được đánh số, 1. wash, hoặc nothing to do, còn inspect trả về #<TodoList 3 items>.
Code được cung cấp thêm từng dòng đầu vào bằng cách nối chuỗi <<, sau đó in danh sách, p của danh sách, các công việc được đánh số bằng ! thông qua each.with_index(1) như 1! wash, số lượng công việc có chứa o và công việc đầu tiên theo thứ tự bảng chữ cái.
Đặt code của bạn trong todo_list.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 'todo_list'
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
input << line.chomp
end
list = input.reduce(TodoList.new) { |l, task| l << task }
puts list
p list
list.each.with_index(1) { |task, n| puts "#{n}! #{task}" }
puts "with o: #{list.count { |t| t.include?("o") }}"
puts "first: #{list.min}"
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ệ8Phương thức đặc biệt
Tính bằng nhau và hashPhương thức toán tửTruy cập theo chỉ số và thêm phần tửBộ sưu tập tùy chỉnhÔn tập: phân sốTự luyện tập: Trình biên dịch Ruby online