אינדוקס והוספה
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 39 מתוך 57.
obj[key] קורא למתודה [], ו־obj[key] = value קורא למתודה []=. הגדרתן מעניקה למחלקה תחביר של סוגריים מרובעים כמו של מערכים ושל גיבובים, עם כל משמעות שמתאימה לה:
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"]פלט:
7
0[] יכול לקבל כמה ארגומנטים, למשל שורה ועמודה, ולבדוק אותם. IndexError היא השגיאה המקובלת עבור מיקום שאינו קיים:
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פלט:
X.
no cell 3,0<< הוא אופרטור ההוספה. החזרת self ממנו מאפשרת שרשור, כמו list << a << b במערכים:
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פלט:
Dune | Emma | Ulyssesהשמה באמצעות []= מחזירה את הערך שהושם, ולא את מה שהמתודה מחזירה, כמו כל מתודת קביעה. סוגריים מרובעים ו־<< מעניקים למחלקה ממשק קטן ומוכר:
inv["apple"] = 5 # קורא ל-[]=("apple", 5), ערך הביטוי הוא 5
inv["apple"] # קורא ל-[]("apple")
shelf << "Dune" << "Emma" # << מחזיר את self, ולכן אפשר לשרשר אותו
board[1, 2] = "X" # []=(1, 2, "X")אתגר
קלהשלם את המחלקה Inventory. inv[name] מחזיר את הכמות של פריט (0 אם הוא לא מוכר), inv[name] = qty מגדיר אותה, ו-inv << name מוסיף אחד מאותו פריט ומחזיר את המלאי, כך שניתן לשרשר קריאות. to_s מחזירה את apple: 3, pear: 1 בסדר אלפביתי של השמות, תוך השמטת פריטים שהכמות שלהם היא 0, או את empty.
הקוד שסופק קורא פקודות: set apple 5, add apple pear pear (שמששרת את << עבור כל שם), get apple ו-print, ומדפיס את התוצאה של get ושל print.
הקוד שלך יופיע בקובץ inventory.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'inventory'
# קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
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
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופוןתרגלו בעצמכם: קומפיילר Ruby אונליין