Truy cập theo chỉ số và thêm phần tử
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 39 trên 57.
obj[key] gọi phương thức [], còn obj[key] = value gọi []=. Định nghĩa các phương thức này giúp lớp có cú pháp dấu ngoặc vuông như mảng và hash, với ý nghĩa tùy theo cách bạn muốn:
class Inventory
def initialize
@stock = Hash.new(0)
end
def [](name)
@stock[name]
end
def []=(name, qty)
@stock[name] = qty
end
end
inv = Inventory.new
inv["apple"] = 5
inv["apple"] += 2
puts inv["apple"]
puts inv["pear"]Đầu ra:
7
0[] có thể nhận nhiều đối số, chẳng hạn như hàng và cột, rồi kiểm tra chúng. IndexError là lỗi thường gặp khi vị trí không tồn tại:
class Board
def initialize(size)
@size = size
@cells = Array.new(size) { Array.new(size, ".") }
end
def [](row, col)
check(row, col)
@cells[row][col]
end
def []=(row, col, mark)
check(row, col)
@cells[row][col] = mark
end
def check(row, col)
raise IndexError, "no cell #{row},#{col}" unless row.between?(0, @size - 1) && col.between?(0, @size - 1)
end
end
b = Board.new(3)
b[1, 1] = "X"
puts b[1, 1] + b[0, 0]
begin
b[3, 0]
rescue IndexError => e
puts e.message
endĐầu ra:
X.
no cell 3,0<< là toán tử nối thêm. Trả về self từ toán tử này cho phép bạn nối chuỗi lệnh, như list << a << b trên mảng:
class Shelf
def initialize
@books = []
end
def <<(title)
@books << title
self
end
def to_s
@books.join(" | ")
end
end
shelf = Shelf.new
shelf << "Dune" << "Emma" << "Ulysses"
puts shelfĐầu ra:
Dune | Emma | UlyssesPhép gán thông qua []= trả về giá trị được gán, chứ không phải giá trị mà phương thức trả về, giống như mọi phương thức setter. Dấu ngoặc vuông và << tạo cho một lớp một giao diện nhỏ, quen thuộc:
inv["apple"] = 5 # gọi []=("apple", 5), biểu thức (expression) có giá trị là 5
inv["apple"] # gọi []("apple")
shelf << "Dune" << "Emma" # << trả về self nên có thể gọi liên tiếp
board[1, 2] = "X" # []=(1, 2, "X")Thử thách
DễHoàn thiện lớp Inventory. inv[name] trả về số lượng của một món hàng (0 nếu chưa biết), inv[name] = qty đặt số lượng đó, còn inv << name thêm một món hàng đó và trả về kho hàng để có thể nối chuỗi các lệnh gọi. to_s trả về apple: 3, pear: 1 theo thứ tự bảng chữ cái của tên, bỏ qua các món hàng có số lượng 0, hoặc trả về empty.
Code được cung cấp đọc các lệnh: set apple 5, add apple pear pear (lệnh này nối chuỗi << cho từng tên), get apple và print, rồi in kết quả của get và print.
Code của bạn nằm trong inventory.rb. main.rb chứa code đầu vào/đầu ra được cung cấp và không thể chỉnh sửa.
Tự làm thử
require_relative 'inventory'
# Đoạn code đầu vào/đầu ra có sẵn: giữ nguyên
input = []
while (line = gets)
input << line.chomp
end
inv = Inventory.new
input.each do |line|
cmd, *args = line.split
case cmd
when "set" then inv[args[0]] = args[1].to_i
when "add" then args.reduce(inv) { |target, name| target << name }
when "get" then puts inv[args[0]]
else puts inv
end
end
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