מודולים ו-include
חלק מהיחידה תכנות מונחה עצמים במסלול ה-Ruby של Coddy. שיעור 27 מתוך 57.
מודול הוא קבוצה בעלת שם של מתודות. הוא לא יכול ליצור אובייקטים, אבל מחלקה יכולה לבצע בו include, ואז לכל מופע יש את המתודות של המודול כאילו המחלקה הגדירה אותן. זה נקרא מיקסין:
module Greetable
def greet
"Hello, I am #{name}"
end
end
class Person
include Greetable
attr_reader :name
def initialize(name)
@name = name
end
end
puts Person.new("Ada").greetפלט:
Hello, I am Adaהמתודות של מודול יכולות לקרוא למתודות שהמחלקה מספקת, כמו name שלמעלה. לכן מודול אחד יכול לשמש מחלקות שונות מאוד, כל עוד כל אחת מהן מספקת את מה שהמודול משתמש בו:
module Greetable
def greet
"Hello, I am #{name}"
end
end
class Robot
include Greetable
def name
"R2"
end
end
class City
include Greetable
def name
"Paris"
end
end
puts Robot.new.greet
puts City.new.greetפלט:
Hello, I am R2
Hello, I am Parisלמחלקה יש מחלקת־על אחת בלבד, אך היא יכולה לכלול כל מספר של מודולים. include? בודקת אם מחלקה כוללת מודול, והמודול מופיע ב־ancestors, מיד אחרי המחלקה — שם Ruby מחפשת את המתודות שלה:
module Swimmer
def swim
"swimming"
end
end
module Flyer
def fly
"flying"
end
end
class Duck
include Swimmer
include Flyer
end
d = Duck.new
puts "#{d.swim}, #{d.fly}"
puts Duck.include?(Flyer)
p Duck.ancestors.take(3)פלט:
swimming, flying
true
[Duck, Flyer, Swimmer]מודולים גם מקבצים מחלקות וקבועים קשורים תחת שם אחד, מרחב שמות, כדי ששמות לא יתנגשו. Shop::Item ו-Game::Item הן מחלקות שונות:
module Shop
TAX = 0.2
class Item
def label
"shop item, tax #{TAX}"
end
end
end
puts Shop::Item.new.label
puts Shop::TAXפלט:
shop item, tax 0.2
0.2אתגר
קלהשלימו את המודולים והמחלקות. Greetable#greet מחזירה את Hello, I am Ada, תוך שימוש ב-name של האובייקט. Walkable#walk(steps) מוסיפה צעדים למונה שנשמר ב-@steps (שמתחיל ב-nil בפעם הראשונה) ומחזירה את Ada walked 30 steps, הסכום המצטבר. Person כוללת את שני המודולים; Robot כוללת רק את Greetable, ושמה הוא R- ואחריו מספר סידורי.
הקוד שסופק יוצר אדם ורובוט מהשורה הראשונה (Ada 7), ואז מריץ את הפקודות greet p, greet r או walk 10 (עבור האדם), מדפיס את התוצאה של כל אחת מהן, ולבסוף את robot walks: false.
הקוד שלכם ייכתב בקבצים greetable.rb, walkable.rb, person.rb ו-robot.rb. הקובץ main.rb מכיל את קוד הקלט/פלט שסופק ואי אפשר לערוך אותו.
נסו בעצמכם
require_relative 'greetable'
require_relative 'walkable'
require_relative 'person'
require_relative 'robot'
# קוד הקלט/פלט שסופק: יש להשאיר אותו כפי שהוא
input = []
while (line = gets)
input << line.chomp
end
name, serial = input[0].split
person = Person.new(name)
robot = Robot.new(serial)
input.drop(1).each do |line|
command, arg = line.split
if command == "walk"
puts person.walk(arg.to_i)
else
target = arg == "p" ? person : robot
puts target.greet
end
end
puts "robot walks: #{Robot.include?(Walkable)}"
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה תכנות מונחה עצמים
3מתודות ומשתנים של מחלקה
מתודות של מחלקהמשתני מופע של מחלקהקבועיםמתודות ליצירת מופעיםסיכום – קודי קופון6מודולים ומיקסינים
מודולים ו-includeהרחבת אובייקטיםהמודול Comparableהמודול Enumerableסיכום - ליגת הספורטתרגלו בעצמכם: קומפיילר Ruby אונליין