self במתודות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 9 מתוך 57.
בתוך מתודה, name = value תמיד יוצר משתנה מקומי, גם כשהמחלקה כוללת setter בשם name=. כדי לקרוא ל-setter, יש לכתוב את המקבל: self.name = value:
class Player
attr_accessor :level
def initialize
@level = 1
end
def broken_level_up
level = level + 1
rescue NoMethodError
puts "level is a new local variable here, still nil"
end
def level_up
self.level = level + 1
end
end
p1 = Player.new
p1.broken_level_up
p1.level_up
puts p1.levelפלט:
level is a new local variable here, still nil
2לפעולות קריאה אין צורך ב־self.: הקריאות ל־level ול־self.level מפעילות את אותה מתודה. בסגנון המקובל כותבים self. רק במקומות שבהם Ruby דורשת זאת, לפני סַדְרָן:
class Rect
attr_accessor :w, :h
def initialize(w, h)
@w = w
@h = h
end
def area
w * h
end
def double!
self.w = w * 2
self.h = self.h * 2
self
end
end
puts Rect.new(2, 3).double!.areaפלט:
24קריאה ל-setter מתוך initialize באמצעות self. גורמת לאובייקטים חדשים לעבור את אותה בדיקה כמו שינויים מאוחרים יותר, כך שהכלל מוגדר במקום אחד:
class Product
attr_reader :price
def initialize(price)
self.price = price
end
def price=(value)
raise ArgumentError, "price must be positive" if value <= 0
@price = value
end
end
puts Product.new(5).price
begin
Product.new(0)
rescue ArgumentError => e
puts e.message
endפלט:
5
price must be positiveמהו self תלוי במקום שבו הקוד רץ. בתוך מתודת מופע, זהו המופע; בגוף המחלקה, מחוץ לכל מתודה, זו המחלקה עצמה:
class Robot
puts "in the class body, self is #{self}"
def whoami
"in a method, self is a #{self.class}"
end
end
puts Robot.new.whoamiפלט:
in the class body, self is Robot
in a method, self is a Robotאתגר
קללמחלקה Account יש setter מותאם אישית balance= שמעלה את ArgumentError עם balance cannot be negative עבור ערך קטן מ־0. השלימו את initialize(owner, balance), את deposit(amount) ואת withdraw(amount) כך שכל שינוי של היתרה יתבצע דרך ה־setter הזה באמצעות self., כולל היתרה ההתחלתית.
הקוד שסופק קורא את שם הבעלים ואת היתרה ההתחלתית, ולאחר מכן פקודות +n (הפקדה) או -n (משיכה). הוא מדפיס Ada: 120 אחרי כל פקודה, או את הודעת השגיאה ואת היתרה ללא שינוי. יתרה התחלתית לא תקינה מדפיסה את הודעת השגיאה בלבד.
הקוד שלכם ייכתב בקובץ account.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק, ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'account'
# קוד קלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
input << line.chomp
end
begin
account = Account.new(input[0], input[1].to_i)
input.drop(2).each do |cmd|
begin
amount = cmd[1..].to_i
cmd.start_with?("+") ? account.deposit(amount) : account.withdraw(amount)
rescue ArgumentError => e
puts e.message
end
puts "#{account.owner}: #{account.balance}"
end
rescue ArgumentError => e
puts e.message
end
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופוןתרגלו בעצמכם: קומפיילר Ruby אונליין