מטא־מתודת __index
חלק מהיחידה לוגיקה וזרימת התוכנית במסלול ה-Lua של Coddy. שיעור 18 מתוך 54.
עכשיו, כשאתה יודע איך להצמיד מטא־טבלאות לטבלאות, הגיע הזמן ללמוד על המתודה המטא־חשובה ביותר: __index. המתודה המטא־הזו קובעת מה קורה כשמנסים לגשת למפתח שאינו קיים בטבלה.
בדרך כלל, כשמחפשים מפתח שאינו נמצא בטבלה, Lua מחזירה nil. אבל כשלמטבלה יש מטא־טבלה עם שדה __index, Lua תבדוק את השדה הזה במקום זאת. אם __index מפנה לטבלה אחרת, Lua תחפש שם את המפתח:
local defaults = {
health = 100,
speed = 10
}
local player = {name = "Alice"}
local meta = {__index = defaults}
setmetatable(player, meta)
print(player.name) -- פלט: Alice
print(player.health) -- פלט: 100בדוגמה הזו, ל־player יש רק מפתח name. כשניגשים אל player.health, Lua לא מוצאת אותו בתוך player, ולכן בודקת את השדה __index של טבלת המטא. מכיוון ש־__index מצביע על הטבלה defaults, Lua מחפשת שם ומוצאת health = 100.
כך נוצר מנגנון חלופי שבו טבלה אחת יכולה לספק ערכי ברירת מחדל לטבלה אחרת. הטבלה המקורית שומרת על הערכים שלה, אך כל מפתח חסר נבדק אוטומטית בטבלת ברירת המחדל.
__index יכול להיות גם פונקציה. כשמפתח חסר, Lua קוראת לה עם הטבלה והמפתח, ומשתמשת בערך שהיא מחזירה:
local scores = {alice = 12}
setmetatable(scores, {
__index = function(t, key)
return 0 -- כל שם חסר נחשב ל-0
end
})
print(scores.alice) -- פלט: 12
print(scores.bob) -- פלט: 0טבלה מספקת ערכי ברירת מחדל קבועים; פונקציה יכולה לחשב ערך עבור כל מפתח חסר.
אתגר
קלכתבו פונקציה createCharacterWithDefaults שמקבלת את name ואת level ומחזירה טבלת דמות עם ערכי ברירת מחדל לנתונים.
צרו טבלת דמות עם השם והרמה שסופקו. השתמשו במטא־טבלה עם __index כדי לספק ערכי ברירת מחדל לכל נתון חסר (health, mana, strength).
לוגיקה:
- צרו טבלת ברירות מחדל עם המפתחות:
health = 100,mana = 50,strength = 10 - צרו טבלת דמות עם המפתחות:
name(השם שסופק) ו-level(הרמה שסופקה) - צרו מטא־טבלה שבה
__indexמפנה לטבלת ברירות המחדל - חברו את המטא־טבלה לטבלת הדמות באמצעות
setmetatable() - החזירו את טבלת הדמות
פרמטרים:
name(מחרוזת): שם הדמותlevel(מספר): רמת הדמות
ערך מוחזר: טבלת דמות עם שם, רמה ונתוני ברירת מחדל שנגישים דרך המטא־טבלה (טבלה)
נסו בעצמכם
function createCharacterWithDefaults(name, level)
-- כתבו כאן את הקוד
end
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.
כל השיעורים ביחידה לוגיקה וזרימת התוכנית
1איטרציה מתקדמת בטבלאות
איטרציה באמצעות pairs()איטרציה באמצעות ipairs()pairs() לעומת ipairs()סיכום – גיליון דמות2פונקציות נוספות של ספריית הטבלאות
table.concat()בניית טבלה ו־unpack()table.sort()מיון מותאם אישית באמצעות פונקציותסיכום – לוח שיאיםתרגלו בעצמכם: קומפיילר Lua אונליין