אוספים מותאמים אישית
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 40 מתוך 57.
מחלקת אוסף משלבת כמה מתודות מיוחדות: each עם Enumerable, << להוספה, size, ו-to_s ו-inspect להדפסה. גם each אמורה לעבוד ללא בלוק, ולהחזיר enumerator באמצעות to_enum, כפי שעושים מערכים:
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") }פלט:
1. wash
2. shop
3. cook
["shop", "cook"]block_given? בודקת אם הקורא העביר בלוק. האנומרייטור שמוחזר בלעדיו תומך בשרשור, למשל each.with_index, each_slice או 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פלט:
3
2
[[5, 4], [3, 2], [1]]to_s הוא הטקסט הידידותי למשתמשים, ו־inspect הוא סיכום קצר למתכנתים. עבור אוסף, inspect מציג בדרך כלל את המחלקה ואת הגודל במקום כל איבר ואיבר:
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פלט:
1. wash
2. shop
#<TodoList 2 פריטים>Enumerable מספקת את count, אך לא את size, empty?, << או []: אלה שייכים למחלקה, כי רק היא יודעת כיצד האיברים מאוחסנים. הגדרתן גורמת לאוסף להרגיש כמו מערך עבור מי שקוראים לו:
def size
@items.size
end
def empty?
@items.empty?
end
def [](index)
@items[index]
endאתגר
קלהשלם את המחלקה TodoList. << מוסיף טקסט של משימה ומחזיר את הרשימה. each מניב את המשימות ומחזיר to_enum(:each) ללא בלוק. כלול את Enumerable. size מחזיר את מספר המשימות. to_s מחזיר את המשימות כשורות ממוספרות, 1. wash, או nothing to do, ו-inspect מחזיר #<TodoList 3 items>.
הקוד שסופק מוסיף כל שורת קלט באמצעות שרשור <<, ואז מדפיס את הרשימה, את p של הרשימה, את המשימות שממוספרות עם ! באמצעות each.with_index(1) כמו 1! wash, את מספר המשימות שמכילות o, ואת המשימה הראשונה בסדר אלפביתי.
הקוד שלך נמצא בקובץ todo_list.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'todo_list'
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
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}"
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופוןתרגלו בעצמכם: קומפיילר Ruby אונליין