Menu
Coddy logo textTech

מקרה ומחלקות

חלק מהיחידה תכנות מונחה עצמים במסלול ה-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
challenge icon

אתגר

קל

השלם את פונקציית העזר 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)) }
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Ruby אונליין