Menu
CoddyTech

אינדוקס והוספה

חלק מהיחידה תכנות מונחה עצמים במסלול ה-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")
challenge icon

אתגר

קל

השלימו את המחלקה 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
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Ruby אונליין