אוספים מותאמים אישית
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 40 מתוך 57.
מחלקת אוסף משלבת כמה מתודות מיוחדות: each יחד עם Enumerable, את << להוספה, את size, ואת to_s ו-inspect להדפסה. each אמורה לעבוד גם ללא בלוק, ולהחזיר מונה באמצעות 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 אונליין