זהות ושוויון
חלק מהיחידה תכנות מונחה עצמים במסלול ה-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פלט:
1equal? בודקת אם שתי הפניות מצביעות על אותו אובייקט, ו-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
falsedup יוצרת אובייקט חדש עם עותקים של משתני המופע. הקצאת ערך חדש לעותק לא משנה את המקור, אבל מערך או מחרוזת שבתוכו עדיין משותפים לשניהם, כי רק ההפניה הועתקה:
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"]אתגר
קלהשלימו את המחלקה 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]}"
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופוןתרגלו בעצמכם: קומפיילר Ruby אונליין