אינדוקס והוספה
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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 אונליין