Menu
Coddy logo textTech

לוגיקת אימות

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

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

כאן שיטות setter הופכות לעוצמתיות. במקום רק להציב ערך, setter יכול לבדוק אם הערך החדש הגיוני לפני שהוא מקבל אותו:

local Person = {}
Person.__index = Person

function Person:new(name, age)
    local obj = {
        _name = name,
        _age = age
    }
    setmetatable(obj, Person)
    return obj
end

function Person:setAge(newAge)
    if newAge < 0 then
        print("Error: Age cannot be negative")
        return
    end
    self._age = newAge
end

כשמישהו קורא ל־person:setAge(-5), המתודה מזהה את הקלט הלא תקין ומסרבת לעדכן. מצב האובייקט נשאר עקבי. ללא ההגנה הזאת, נתונים שגויים עלולים לפגוע בתוכנית שלך מבלי שתבחין בכך: דמיין חישוב של קצבאות פרישה לפי גיל שלילי.

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

challenge icon

אתגר

קל

בואו נבנה מחלקה Player שמגינה על מאפייני הבריאות והרמה שלה באמצעות לוגיקת אימות בשיטות setter! כך נבטיח שדמויות במשחק לעולם לא יגיעו לנתונים בלתי אפשריים.

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

  • Player.lua: צור מחלקה שמנהלת את הנתונים של השחקן באמצעות אימות מתאים. הבנאי :new(name) צריך לאתחל את השחקן עם שם, כאשר _health מוגדר ל-100, ו-_level מוגדר ל-1. כלול את השיטות הבאות:
    • :getName(): מחזירה את שם השחקן
    • :getHealth(): מחזירה את הבריאות הנוכחית
    • :getLevel(): מחזירה את הרמה הנוכחית
    • :setHealth(value): מעדכנת את הבריאות רק אם הערך הוא בין 0 ל-100 (כולל). אם הערך אינו תקין, הדפס Error: Health must be between 0 and 100 ואל תשנה את הערך.
    • :setLevel(value): מעדכנת את הרמה רק אם הערך הוא 1 או יותר. אם הערך אינו תקין, הדפס Error: Level must be at least 1 ואל תשנה את הערך.
  • main.lua: טען את המודול Player שלך וקרא שם של שחקן, ולאחר מכן שני ערכים לבדיקת שיטות ה-setter. צור שחקן, נסה להגדיר את הבריאות שלו לערך הראשון, נסה להגדיר את הרמה שלו לערך השני, ואז הדפס את הנתונים הסופיים של השחקן.

יתקבלו שלושה קלטים:

  1. שם השחקן
  2. ערך בריאות שיש לנסות להגדיר (מספר, שיכול להיות תקין או לא תקין)
  3. ערך רמה שיש לנסות להגדיר (מספר, שיכול להיות תקין או לא תקין)

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

Name: {name}
Health: {finalHealth}
Level: {finalLevel}

לדוגמה, אם הקלטים הם Hero, -20 ו-5, הפלט צריך להיות:

Error: Health must be between 0 and 100
Name: Hero
Health: 100
Level: 5

שיטת ה-setter של הבריאות דחתה את -20 (והשאירה את הבריאות על 100), ואילו שיטת ה-setter של הרמה קיבלה את 5 כערך תקין.

אם הקלטים הם Warrior, 75 ו-0, הפלט צריך להיות:

Error: Level must be at least 1
Name: Warrior
Health: 75
Level: 1

נסו בעצמכם

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

-- קרא את הקלטים
local name = io.read()
local healthValue = tonumber(io.read())
local levelValue = tonumber(io.read())

-- TODO: צור שחקן חדש עם השם הנתון

-- TODO: נסה להגדיר את הבריאות של השחקן ל-healthValue

-- TODO: נסה להגדיר את הרמה של השחקן ל-levelValue

-- TODO: הדפס את הנתונים הסופיים של השחקן בפורמט:
-- שם: {name}
-- בריאות: {finalHealth}
-- רמה: {finalLevel}
quiz iconבחנו את עצמכם

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

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

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