Menu
Coddy logo textTech

קישור באמצעות __index

חלק מהיחידה תכנות מונחה עצמים במסלול ה-Lua של Coddy. שיעור 7 מתוך 70.

יש לך טבלת אב־טיפוס עם מאפיינים ומתודות, אבל איך גורמים לאובייקט חדש להשתמש בה בפועל? התשובה טמונה במתאמתודה __index.

כשניגשים למפתח שאינו קיים בטבלה, Lua מחזירה בדרך כלל nil. עם זאת, אם לטבלה יש מטא־טבלה עם שדה __index, Lua תחפש שם במקום זאת. על ידי הגדרת __index כך שיצביע על אב הטיפוס שלך, כל המפתחות החסרים יימצאו אוטומטית באב הטיפוס:

local Dog = {
    species = "Canis familiaris",
    legs = 4
}

function Dog:bark()
    print("Woof!")
end

-- צור מופע ריק
local myDog = {}

-- קשר אותו לאב הטיפוס
setmetatable(myDog, { __index = Dog })

print(myDog.species)  -- פלט: Canis familiaris
myDog:bark()          -- פלט: Woof!

הטבלה myDog ריקה לחלוטין, ובכל זאת הגישה אל myDog.species עובדת. כש-Lua לא מוצאת את species ב-myDog, היא בודקת את __index של המטא-טבלה ומוצאת אותו ב-Dog.

זהו הבסיס של תכנות מונחה עצמים ב-Lua. למופע יכולים להיות נתונים ייחודיים משלו, בעוד שהתנהגות משותפת נמצאת באב־הטיפוס. בשיעור הבא תלמדו איך לעטוף את התבנית הזו בפונקציית בנאי מסודרת.

challenge icon

אתגר

קל

עכשיו ניישם את מטא-מתודה __index! תיצרו אבטיפוס ותקשרו אליו מופע, כך שהמופע יוכל לגשת למאפיינים ולמתודות שאין לו ישירות.

תארגנו את הקוד שלכם בשני קבצים:

  • Robot.lua: הגדירו טבלת אבטיפוס בשם Robot עם:
    • שדה model שהערך שלו הוא "RX-100"
    • שדה batteryLevel שהערך שלו הוא 100
    • מתודת :status() שמדפיסה את המצב הנוכחי של הרובוט
    החזירו את הטבלה בסוף הקובץ.
  • main.lua: טענו את מודול Robot, ואז צרו טבלת מופע ריקה וְקשרו אותה לאבטיפוס Robot באמצעות setmetatable עם __index. כך המופע הריק שלכם יוכל לגשת לכל מה שנמצא באבטיפוס.

תקבלו קלט אחד: שם שיש לשייך למופע הרובוט שלכם.

לאחר קישור המופע לאבטיפוס:

  1. שייכו את שם הקלט לשדה name של המופע שלכם (כך השם יהיה ייחודי למופע)
  2. קראו למתודת :status() במופע שלכם

מתודת :status() שלכם צריכה להדפיס בפורמט המדויק הזה:

[name] ([model]) - Battery: [batteryLevel]%

לדוגמה, אם הקלט הוא Sparky, הפלט אמור להיות:

Sparky (RX-100) - Battery: 100%

שימו לב שלמופע יש name משלו, אבל הוא ניגש אל model ואל batteryLevel מהאבטיפוס דרך הקישור __index.

נסו בעצמכם

-- קרא את הקלט
local name = io.read()

-- טען את המודול Robot באמצעות require
local Robot = require('Robot')

-- TODO: צור טבלת מופע ריקה

-- TODO: קשר את המופע לאב־הטיפוס Robot באמצעות setmetatable עם __index

-- TODO: הקצה את השם שהתקבל בקלט לשדה name של המופע שלך

-- TODO: קרא למתודה :status() של המופע שלך
quiz iconבחנו את עצמכם

השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.

כל השיעורים ביחידה תכנות מונחה עצמים

תרגלו בעצמכם: קומפיילר Lua אונליין