Menu
CoddyTech

זהות ושוויון

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

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

class Box
  attr_accessor :count

  def initialize
    @count = 0
  end
end

a = Box.new
b = a
b.count += 1
puts a.count

פלט:

1

equal? בודקת אם שתי הפניות מצביעות על אותו אובייקט, ו-object_id הוא המספר הייחודי של כל אובייקט. במחלקות משלך, == עושה זאת כברירת מחדל, ולכן שני אובייקטים בעלי אותם ערכים אינם שווים:

class Point
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end
end

a = Point.new(1, 2)
b = Point.new(1, 2)
c = a
puts a == b
puts a.equal?(b)
puts a.equal?(c)
puts a.object_id == c.object_id

פלט:

false
false
true
true

הגדירו את == כדי להשוות לפי ערך. המתודות include?, index ו־delete על מערכים משתמשות ב־==, ולכן הן מוצאות גם אובייקטים שווים. בדקו קודם את המחלקה של other, כדי שהשוואה למספר או ל־nil תחזיר false במקום להיכשל:

class Point
  attr_reader :x, :y

  def initialize(x, y)
    @x = x
    @y = y
  end

  def ==(other)
    other.is_a?(Point) && x == other.x && y == other.y
  end
end

a = Point.new(1, 2)
puts a == Point.new(1, 2)
puts a == 5
puts [Point.new(0, 0), Point.new(1, 2)].include?(a)
puts a.equal?(Point.new(1, 2))

פלט:

true
false
true
false

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

class Team
  attr_accessor :name, :players

  def initialize(name)
    @name = name
    @players = []
  end
end

a = Team.new("Reds")
b = a.dup
b.name = "Blues"
b.players << "Ada"
puts a.name
p a.players

פלט:

Reds
["Ada"]
challenge icon

אתגר

קל

השלימו את המחלקה Point כך ששתי נקודות עם אותן קואורדינטות יהיו שוות זו לזו באמצעות ==, והשוואה של נקודה לכל דבר אחר תחזיר false. to_s מחזירה (1, 2).

הקוד שסופק קורא נקודות כשורות בפורמט x,y. עבור כל נקודה הוא מדפיס (1, 2) same as first: true או false, ואז שומר רשימה של נקודות שונות באמצעות include? ולבסוף מדפיס distinct: 3 והאם הנקודה הראשונה שווה לטקסט "1,2".

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

נסו בעצמכם

require_relative 'point'

# קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
  input << line.chomp
end
points = input.map { |line| Point.new(*line.split(",").map(&:to_i)) }
points.each { |pt| puts "#{pt} same as first: #{pt == points[0]}" }
distinct = []
points.each { |pt| distinct << pt unless distinct.include?(pt) }
puts "distinct: #{distinct.size}"
puts "equals text: #{points[0] == input[0]}"
quiz iconבחנו את עצמכם

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

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

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