מקרה ומחלקות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 35 מתוך 57.
case יכולה להתפצל לפי המחלקה של ערך. when Integer תואמת לכל מספר שלם, כי case משווה באמצעות ===, ו־Integer === 5 שואלת אם 5 הוא Integer (is_a?):
def describe(value)
case value
when Integer then "integer #{value}"
when Float then format("float %.2f", value)
when String then "text of #{value.size} chars"
when nil then "nothing"
else "other: #{value.class}"
end
end
[5, 2.5, "hi", nil, [1, 2]].each { |v| puts describe(v) }פלט:
integer 5
float 2.50
text of 2 chars
nothing
other: Arrayמכיוון ש־=== במחלקה פועל לפי is_a?, תנאי when עם מחלקת־על מתאים גם למחלקות המשנה שלה. סדרו את הענפים מהמחלקה הספציפית ביותר לכללית ביותר:
class Animal
end
class Dog < Animal
end
def kind(x)
case x
when Dog then "a dog"
when Animal then "some animal"
else "not an animal"
end
end
puts kind(Dog.new)
puts kind(Animal.new)
puts kind("Rex")
puts Animal === Dog.newפלט:
a dog
some animal
not an animal
trueאפשר לציין כמה מחלקות ב־when אחד, והענפים יכולים לבצע עבודה ממשית עם הערך, למשל לסכם מבנה מקונן של טיפוסים מעורבים:
def total(value)
case value
when Integer, Float then value
when String then value.to_f
when Array then value.sum { |v| total(v) }
when Hash then total(value.values)
else 0
end
end
puts total([1, "2.5", { a: 3, b: [4, nil] }])פלט:
10.5הסתעפות לפי מחלקות מתאימה לערכים שלמחלקות שלהם אי אפשר להוסיף שיטות חדשות, כמו מספרים, מחרוזות ומערכים, או נתונים ממקור חיצוני. במחלקות משלך, העדף פולימורפיזם: מחלקה חדשה צריכה שיטה חדשה, ולא הסתעפות חדשה בכל case:
# מחלקות משלך: תן לכל אחת לענות
shape.area
# ערכים מובנים שמגיעים מבחוץ: פצל לפי המחלקה
case value
when Integer then ...
when String then ...
endאתגר
קלהשלם את פונקציית העזר describe(value) בקובץ functions.rb באמצעות case על המחלקה של הערך. היא מחזירה integer 5 (odd) או integer 4 (even), את float 2.50 עם שתי ספרות אחרי הנקודה העשרונית, את text "hi" (2 chars), את list of 3: 1, a, 2.5 (כאשר איברי הרשימה מחוברים באמצעות to_s), את nothing עבור nil, ואת other Symbol עבור כל ערך אחר. סמלים הם הסוג האחר היחיד שמופיע בבדיקות.
הקוד שסופק הופך כל שורת קלט לערך (מספרים שלמים, מספרים עשרוניים, רשימות [a,b], nil, סמלי :name או טקסט), ומדפיס את describe עבור כל אחד מהם.
הקוד שלך ייכנס לקובץ functions.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'functions'
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
input << line.chomp
end
def parse(text)
return Integer(text) if text.match?(/\A-?\d+\z/)
return Float(text) if text.match?(/\A-?\d+\.\d+\z/)
return nil if text == "nil"
return text[1..].to_sym if text.start_with?(":")
return text[1...-1].split(",").map { |t| parse(t) } if text.start_with?("[")
text
end
input.each { |line| puts describe(parse(line)) }
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופוןתרגלו בעצמכם: קומפיילר Ruby אונליין