Menu
Coddy logo textTech

מתודות ליצירת מופעים

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 15 מתוך 57.

שיטת מפעל היא שיטת מחלקה שיוצרת ומחזירה מופע. היא נותנת שם לאחת הדרכים ליצור אובייקט. בתוך שיטת מחלקה, new פירושו self.new:

class Temperature
  attr_reader :celsius

  def initialize(celsius)
    @celsius = celsius
  end

  def self.from_fahrenheit(f)
    new((f - 32) * 5 / 9.0)
  end

  def self.freezing
    new(0)
  end
end

puts Temperature.from_fahrenheit(212).celsius
puts Temperature.freezing.celsius

פלט:

100.0
0

הפיכת טקסט לאובייקט היא משימה נפוצה עבור מפעל. הניתוח מתבצע לצד המחלקה, ו-initialize נשארת פשוטה:

class Duration
  attr_reader :seconds

  def initialize(seconds)
    @seconds = seconds
  end

  def self.parse(text)
    new(text.split(":").map(&:to_i).reduce(0) { |acc, part| acc * 60 + part })
  end
end

puts Duration.parse("1:30").seconds
puts Duration.parse("2:00:05").seconds

פלט:

90
7205

מפעל יכול לסרב לקלט לא תקין. החזרת nil מאפשרת לקוד הקורא לבדוק את התוצאה באמצעות if; העלאת שגיאה עוצרת את התוכנית, אלא אם הקוד הקורא תופס אותה:

class Color
  attr_reader :hex

  def initialize(hex)
    @hex = hex
  end

  def self.parse(text)
    return nil unless text.match?(/\A#[0-9a-f]{6}\z/i)

    new(text.downcase)
  end
end

["#FF8800", "orange"].each do |text|
  color = Color.parse(text)
  puts color ? "ok #{color.hex}" : "not a color: #{text}"
end

פלט:

ok #ff8800
not a color: orange

private_class_method :new הופך את new לזמינה לקריאה רק מתוך המחלקה, כך שהמפעלים הופכים לדרך היחידה ליצור אובייקט:

class Money
  attr_reader :cents

  def initialize(cents)
    @cents = cents
  end
  private_class_method :new

  def self.from_cents(cents)
    new(cents)
  end
end

puts Money.from_cents(250).cents
begin
  Money.new(250)
rescue NoMethodError => e
  puts e.message
end

פלט:

250
private method `new' called for class Money
challenge icon

אתגר

קל

השלימו את המחלקה Duration. initialize(seconds) שומרת מספר שניות. מפעל היצירה Duration.parse(text) קורא ערכים בפורמט m:ss או h:mm:ss, מפעל היצירה Duration.from_minutes(m) מקבל מספר שלם של דקות, plus(other) מחזירה Duration חדשה עם הסכום, ו-to_s מחזירה ערך בפורמט h:mm:ss עם דקות ושניות בנות שתי ספרות.

הקוד שסופק קורא משכי זמן: שורות כמו 45m מטופלות באמצעות from_minutes, ושאר השורות באמצעות parse. הוא מדפיס כל משך זמן ולבסוף total 1:47:10.

הקוד שלכם יופיע בתוך duration.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.

נסו בעצמכם

require_relative 'duration'

# קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
  input << line.chomp
end
durations = input.map do |line|
  line.end_with?("m") ? Duration.from_minutes(line.to_i) : Duration.parse(line)
end
durations.each { |d| puts d }
puts "total #{durations.reduce(Duration.new(0)) { |sum, d| sum.plus(d) }}"
quiz iconבחנו את עצמכם

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

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

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