הרחבת אובייקטים
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 28 מתוך 57.
extend מוסיף את המתודות של מודול לאובייקט אחד במקום לכל המופעים. הרחבה של מחלקה מוסיפה אותן לאובייקט המחלקה, ולכן הן הופכות למתודות מחלקה:
module Describable
def describe
"#{name} has #{instance_methods(false).size} methods"
end
end
class Dog
extend Describable
def bark
"Woof"
end
def sit
"sits"
end
end
puts Dog.describeפלט:
Dog has 2 methodsמודול שמשתמשים בו עם extend יכול לשמור מצב במשתני מופע של המחלקה. כל מחלקה שמרחיבה אותו מקבלת עותק משלה, כמו משתני מופע של מחלקה:
module Counted
def created
@created ||= 0
end
def record
@created = created + 1
end
end
class Order
extend Counted
end
class Invoice
extend Counted
end
Order.record
Order.record
Invoice.record
puts "#{Order.created} #{Invoice.created}"פלט:
2 1extend פועל גם על אובייקט יחיד. רק האובייקט הזה מקבל את המתודות; מופעים אחרים של המחלקה שלו נשארים ללא שינוי, ו-is_a? מחזיר true רק עבור האובייקט שהורחב:
module Shiny
def polish
"#{self} is shining"
end
end
a = "car"
b = "bike"
a.extend(Shiny)
puts a.polish
puts a.is_a?(Shiny)
puts b.respond_to?(:polish)פלט:
car is shining
true
falseשתי מילות המפתח מציבות את המתודות של אותו מודול במקומות שונים. include הופכת אותן למתודות מופע של מחלקה, ו-extend הופכת אותן למתודות של האובייקט היחיד שמורחב:
class Order
include Printable # order.print_me (כל מופע)
extend Counted # Order.record (המחלקה עצמה)
end
item.extend(Shiny) # item.polish (רק האובייקט הזה)אתגר
קלהשלם את המודול Registry, שבו מחלקות משתמשות באמצעות extend. register(name) מוסיפה שם לרשימה של המחלקה עצמה, שנשמרת ב־@entries (ונוצרת בשימוש הראשון), ומחזירה את Plugin registered x; אם השם כבר נמצא ברשימה, מוחזר Plugin already has x. entries מחזירה את הרשימה, ו־count את גודלה. גם Plugin וגם Theme מרחיבות את Registry ושומרות רשימות נפרדות.
הקוד שסופק קורא שורות plugin name או theme name, קורא ל־register במחלקה המתאימה ומדפיס את התשובה. לבסוף הוא מדפיס plugins: a, b (2) ו־themes: ..., או none (0) עבור רשימה ריקה.
הקוד שלך ייכנס לקבצים registry.rb, plugin.rb ו־theme.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'registry'
require_relative 'plugin'
require_relative 'theme'
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
input << line.chomp
end
input.each do |line|
kind, name = line.split
target = kind == "plugin" ? Plugin : Theme
puts target.register(name)
end
[["plugins", Plugin], ["themes", Theme]].each do |label, klass|
list = klass.entries.empty? ? "none" : klass.entries.join(", ")
puts "#{label}: #{list} (#{klass.count})"
end
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופון6מודולים ומיקסינים
מודולים ו-includeהרחבת אובייקטיםהמודול Comparableהמודול Enumerableסיכום - ליגת הספורטתרגלו בעצמכם: קומפיילר Ruby אונליין