המודול 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 אונליין