המודול Enumerable
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 30 מתוך 57.
Enumerable הוא המודול שמאחורי שיטות האוסף של מערכים וגיבובים. מחלקה שמגדירה את each, ומחזירה את איבריה בזה אחר זה, וכוללת את Enumerable, מקבלת את map, select, count, sort_by, min_by, sum, include? ועוד עשרות שיטות:
class Playlist
include Enumerable
def initialize(*songs)
@songs = songs
end
def each
@songs.each { |song| yield song }
end
end
list = Playlist.new("Intro", "Dune", "Outro")
puts list.map(&:upcase).join(", ")
puts list.select { |s| s.size > 4 }.inspect
puts list.count
puts list.include?("Dune")פלט:
INTRO, DUNE, OUTRO
["Intro", "Outro"]
3
trueyield מעביר ערך לבלוק שהקורא העביר ל־each. המחלקה קובעת מהו איבר אחד, למשל שורת טקסט, זוג ערכים או אחד מהאובייקטים שלה:
class Inventory
include Enumerable
def initialize
@stock = { "apple" => 3, "pear" => 0, "plum" => 7 }
end
def each
@stock.each { |name, qty| yield name, qty }
end
end
inv = Inventory.new
p inv.select { |_, qty| qty.positive? }.map(&:first)
p inv.max_by { |_, qty| qty }פלט:
["apple", "plum"]
["plum", 7]אין צורך לאחסן את האיברים. each יכולה לחשב אותם תוך כדי, ומתודות כמו first עוצרות את הלולאה מוקדם:
class Squares
include Enumerable
def initialize(limit)
@limit = limit
end
def each
n = 1
while n * n <= @limit
yield n * n
n += 1
end
end
end
p Squares.new(50).to_a
p Squares.new(1000).first(3)
puts Squares.new(100).sumפלט:
[1, 4, 9, 16, 25, 36, 49]
[1, 4, 9]
385כאשר האיברים מגדירים <=>, שיטות המיון של Enumerable, כגון sort, min ו־max, פועלות ללא בלוק. אחרת הן מקבלות בלוק, כמו sort_by ו־min_by:
class Team
include Enumerable
def each(&block)
@players.each(&block) # העבר את הבלוק ישירות הלאה
end
end
team.sort_by(&:age)
team.min_by(&:score)אתגר
קלהשלימו את המחלקה Playlist. היא מכילה אובייקטים מסוג Song (עם title ו-seconds) שנוספים באמצעות add, כוללת את Enumerable ומגדירה את each, שמניבה כל שיר לפי סדר הוספתו.
הקוד שסופק מוסיף שיר אחד בכל שורת קלט (title,seconds) ואז משתמש רק בשיטות של Enumerable על הפלייליסט: הוא מדפיס את מספר השירים, את הכותרות כשהן מחוברות בפסיקים, את האורך הכולל בפורמט m:ss, את הכותרת הארוכה ביותר ואת כותרות השירים שאורכם עולה על 3 דקות, ממוינות בסדר אלפביתי (או none).
הקוד שלכם צריך להיות בקבצים song.rb ו-playlist.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'song'
require_relative 'playlist'
# קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
input << line.chomp
end
list = Playlist.new
input.each do |line|
title, seconds = line.split(",")
list.add(Song.new(title, seconds.to_i))
end
total = list.sum(&:seconds)
long = list.select { |s| s.seconds > 180 }.map(&:title).sort
puts "songs: #{list.count}"
puts "titles: #{list.map(&:title).join(", ")}"
puts format("total: %d:%02d", total / 60, total % 60)
puts "longest: #{list.max_by(&:seconds).title}"
puts "over 3 min: #{long.empty? ? "none" : long.join(", ")}"
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופון6מודולים ומיקסינים
מודולים ו-includeהרחבת אובייקטיםהמודול Comparableהמודול Enumerableסיכום - ליגת הספורטתרגלו בעצמכם: קומפיילר Ruby אונליין