self במתודות
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 9 מתוך 57.
בתוך מתודה, name = value תמיד יוצר משתנה מקומי, גם כאשר למחלקה יש קובע name=. כדי לקרוא לקובע, כתבו את המקבל: 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 דורשת זאת, לפני setter:
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קריאה למגדיר מתוך 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 אונליין