Lua Academy · पाठ

__index और __newindex

__index और __newindex मेटामेथड से फ़ील्ड को पढ़ने और लिखने की क्रियाएँ रोककर संभालें।

पाठ 2, कुल 4 में से12 चरण

__index और __newindex, CoddyKit पर Lua Academy का एक निःशुल्क पाठ है। यह 4 में से 2वाँ पाठ है। इस अध्ययन पथ के 3 तक कोई भी पाठ पूरा पढ़ना निःशुल्क है — इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ व्यावहारिक अभ्यास भी उपलब्ध कराता है। यह Lua Academy सीखने के मार्ग का हिस्सा है और आपकी प्रगति वेब तथा CoddyKit ऐप पर सिंक होती रहती है। Lua Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

__index का पुनरावलोकन

जब Lua ऐसी कुंजी पढ़ने का प्रयास करता है जो टेबल में मौजूद नहीं है, तब __index सक्रिय होता है। यह एक टेबल (प्रोटोटाइप में खोज) या एक फ़ंक्शन (गतिशील गणना) हो सकता है। Lua में यह सबसे अधिक उपयोग किया जाने वाला मेटामेथड है—यह इनहेरिटेंस, डिफ़ॉल्ट मान और विलंबित आरंभीकरण को सक्षम करता है।

local defaults = {timeout=30, retries=3}
local config = setmetatable({timeout=60}, {__index=defaults})

print(config.timeout)   -- 60 (own value)
print(config.retries)   -- 3  (from defaults)
print(config.missing)   -- nil (not in either)

__newindex का सक्रिय होना

जब Lua ऐसी कुंजी लिखने का प्रयास करता है जो अभी तक टेबल में मौजूद नहीं है, तब __newindex सक्रिय होता है। यदि कुंजी पहले से मौजूद है, तो असाइनमेंट सीधे होता है और __newindex सक्रिय नहीं होता।

local proxy = setmetatable({}, {
  __newindex = function(t, k, v)
    print("New key:", k, "=", v)
    rawset(t, k, v)  -- actually store it
  end
})

proxy.x = 10    -- New key: x = 10
proxy.x = 20    -- no trigger! x already exists
print(proxy.x)  -- 20

केवल-पठन टेबलें

केवल-पठन टेबलें बनाने के लिए __newindex का उपयोग करें। सभी लेखन-क्रियाओं को रोककर एक त्रुटि उत्पन्न करें। टेबल में मान संग्रहीत किए बिना उन्हें उपलब्ध कराने के लिए इसे __index के साथ संयोजित करें।

local function readOnly(t)
  return setmetatable({}, {
    __index = t,
    __newindex = function(_, k, _)
      error("attempt to write to read-only table key: " .. tostring(k), 2)
    end
  })
end

local cfg = readOnly({host="localhost", port=8080})
print(cfg.host)    -- localhost
-- cfg.host = "x"  -- ERROR: attempt to write to read-only table

बदलावों पर नज़र रखना

टेबल में होने वाले सभी बदलावों पर नज़र रखने के लिए __newindex का उपयोग करें—यह डीबगिंग, बदलावों का लॉग दर्ज करने या प्रतिक्रियाशील डेटा बाइंडिंग के लिए उपयोगी है। डेटा को एक छिपी हुई "backing" टेबल में रखें और बदलावों को एक लॉग में दर्ज करें।

local log = {}
local data = {}
local tracked = setmetatable({}, {
  __index = data,
  __newindex = function(_, k, v)
    log[#log+1] = {key=k, old=data[k], new=v}
    data[k] = v
  end
})

tracked.name = "Alice"
tracked.age = 30
tracked.name = "Bob"

for _, entry in ipairs(log) do
  print(entry.key, entry.old, "->", entry.new)
end

प्रॉक्सी ऑब्जेक्ट

प्रॉक्सी, पढ़ने और लिखने की सभी क्रियाओं को बीच में रोकने के लिए किसी दूसरे ऑब्जेक्ट को लपेटता है। प्रॉक्सी के रूप में एक खाली टेबल का उपयोग करें, जिसमें __index और __newindex दोनों फ़ंक्शनों की ओर संकेत करें। वास्तविक डेटा एक अलग टेबल में रहता है।

local function makeProxy(target)
  return setmetatable({}, {
    __index = function(_, k) return target[k] end,
    __newindex = function(_, k, v)
      print("Setting", k, "on target")
      target[k] = v
    end,
  })
end

local real = {x=10}
local p = makeProxy(real)
print(p.x)   -- 10 (reads from real)
p.y = 20     -- Setting y on target
print(real.y) -- 20

__index श्रृंखला (इनहेरिटेंस)

__index मेटाटेबल को श्रृंखला में जोड़ने से प्रोटोटाइप इनहेरिटेंस बनता है। जब ऑब्जेक्ट में कोई कुंजी नहीं मिलती, तो Lua पहले वर्ग, फिर पैरेंट वर्ग और इसी तरह आगे जाँच करता है। हर स्तर की अपनी मेटाटेबल होनी चाहिए, जिसका __index अगले स्तर की ओर संकेत करे।

local Base  = {type = "base",  version = 1}
local Child = setmetatable({type = "child"}, {__index = Base})
local Obj   = setmetatable({}, {__index = Child})

print(Obj.type)     -- base? No: child (Child has it)
print(Obj.version)  -- 1 (from Base)
print(Obj.type)     -- child (Child overrides Base.type)

__index से विलंबित आरंभीकरण

पहली बार पहुँचने पर महँगे मानों की गणना और उन्हें कैश करने के लिए फ़ंक्शन-रूप वाले __index का उपयोग करें। पहली बार पढ़ते समय मान की गणना करके उसे सीधे टेबल में संग्रहीत करें (ताकि आगे होने वाले __index आह्वानों को बायपास किया जा सके)।

local lazy = setmetatable({}, {
  __index = function(t, k)
    if k == "expensiveData" then
      print("Computing...")
      local result = {1,2,3,4,5}   -- simulate work
      rawset(t, k, result)
      return result
    end
  end
})

print(lazy.expensiveData)  -- Computing...  then table
print(lazy.expensiveData)  -- (no "Computing" this time)

स्कीमा सत्यापन के लिए __newindex

स्कीमा लागू करने के लिए __newindex का उपयोग करें: केवल पहले से परिभाषित कुंजियों या सही प्रकार के मानों को सेट करने की अनुमति दें। इससे Lua टेबलों में हल्की प्रकार-सुरक्षा जुड़ती है।

local schema = {name="string", age="number", active="boolean"}

local function schemaTable()
  local store = {}
  return setmetatable({}, {
    __index = store,
    __newindex = function(_, k, v)
      local expected = schema[k]
      if not expected then error("unknown key: "..k,2) end
      if type(v) ~= expected then
        error(k.." must be "..expected..", got "..type(v),2)
      end
      store[k] = v
    end
  })
end

local user = schemaTable()
user.name = "Alice"
user.age  = 30
-- user.age = "thirty"  -- ERROR

__index बनाम rawget

__index फ़ंक्शन के अंदर टेबल से मान पढ़ने के लिए rawget का उपयोग करें, ताकि __index फिर से सक्रिय न हो (जिससे अनंत पुनरावृत्ति होगी)। वास्तविक टेबल संग्रहण में बदलाव करने के लिए मेटामेथड के अंदर हमेशा rawget/rawset का उपयोग करें।

local counter = setmetatable({count=0}, {
  __index = function(t, k)
    -- Use rawget to avoid recursion
    local c = rawget(t, "count")
    rawset(t, "count", c + 1)
    return rawget(t, k)
  end
})

print(counter.count)    -- 0 (direct, no __index)
print(counter.missing)  -- nil
print(counter.count)    -- 1 (incremented)

__index और __newindex का संयोजन

सबसे शक्तिशाली पैटर्न है: एक छिपी हुई डेटा टेबल के आधार वाली खाली प्रॉक्सी टेबल में __index और __newindex दोनों का उपयोग करना। इससे पढ़ने और लिखने पर पूरा नियंत्रण मिलता है और बदलावों का पता लगाना, विलंबित लोडिंग तथा पहुँच-नियंत्रण जैसी सुविधाएँ संभव होती हैं।

local function observable(init)
  local data = init or {}
  local listeners = {}
  local obj = setmetatable({}, {
    __index = data,
    __newindex = function(_, k, v)
      local old = data[k]
      data[k] = v
      for _, cb in ipairs(listeners) do cb(k,old,v) end
    end
  })
  obj._onchange = function(_, cb) listeners[#listeners+1]=cb end
  return obj
end

local obs = observable({score=0})
obs:_onchange(function(k,o,n) print(k,o,"->",n) end)
obs.score = 100  -- score  0 -> 100

त्वरित जाँच

__newindex कब सक्रिय नहीं होता?

पुनरावृत्ति: __index और __newindex

मुख्य बिंदु:

  • __index: अनुपस्थित कुंजी पढ़ने पर सक्रिय; टेबल या फ़ंक्शन
  • __newindex: केवल नई कुंजी में लिखने पर सक्रिय
  • पुनरावृत्ति से बचने के लिए मेटामेथड के अंदर rawget/rawset का उपयोग करें
  • पैटर्न: केवल-पठन टेबलें, बदलावों पर नज़र रखना, विलंबित आरंभीकरण, स्कीमा सत्यापन
  • खाली प्रॉक्सी + आधार टेबल = पढ़ने/लिखने पर पूरा नियंत्रण
शुरुआत निःशुल्क

एआई शिक्षक के साथ Lua सीखें — निःशुल्क

अपने ब्राउज़र में वास्तविक कोड लिखें और चलाएँ, चौबीसों घंटे एआई शिक्षक से तुरंत सहायता पाएँ, और वेब या ऐप पर वहीं से शुरू करें जहाँ आपने छोड़ा था।

पाठ्यक्रम
40
पाठ
159

अक्सर पूछे जाने वाले प्रश्न

क्या “__index और __newindex” पाठ निःशुल्क है?

हाँ — Lua Academy अध्ययन पथ के 3 तक कोई भी पाठ, जिसमें “__index और __newindex” भी शामिल है, यहाँ वेब पर पूरा पढ़ना निःशुल्क है। इसके बाद CoddyKit PRO हर पाठ अनलॉक करता है, साथ ही अंतर्निर्मित कोड संपादक और चौबीसों घंटे एआई शिक्षक के साथ इंटरैक्टिव अभ्यास भी उपलब्ध कराता है। Lua Academy पाठ्यक्रम में कुल 4 पाठ शामिल हैं।

“__index और __newindex” में मैं क्या सीखूँगा?

__index और __newindex मेटामेथड से फ़ील्ड को पढ़ने और लिखने की क्रियाएँ रोककर संभालें। आप ब्राउज़र में सीधे चलाए जाने वाले व्यावहारिक कोड के साथ Lua Academy का अभ्यास करते हैं, और पाठ पूरा करते समय 24/7 एआई ट्यूटर आपके प्रश्नों के उत्तर देता है।

क्या Lua Academy शुरू करने के लिए मुझे किसी अनुभव की आवश्यकता है?

पहले के अनुभव की आवश्यकता नहीं है। CoddyKit पर Lua Academy शुरुआती से लेकर उन्नत शिक्षार्थियों तक सभी के लिए व्यवस्थित किया गया है, इसलिए आप यहीं से या शुरुआत से सीखना शुरू कर सकते हैं और अपनी गति से आगे बढ़ सकते हैं। यह 4 में से 2वाँ पाठ है।

“__index और __newindex” पाठ पूरा करने में कितना समय लगता है?

CoddyKit का अधिकांश पाठ लगभग 5–10 मिनट में पूरा हो जाता है। हर पाठ छोटा और संवादात्मक है, इसलिए आप लगातार प्रगति करते हैं और वेब या ऐप पर वहीं से सीखना जारी रख सकते हैं जहाँ आपने छोड़ा था।

क्या मैं इस Lua Academy पाठ में कोड लिख और चला सकता हूँ?

हाँ। हर Lua Academy पाठ में एक अंतर्निर्मित कोड संपादक शामिल है, जिससे आप सीधे अपने ब्राउज़र में वास्तविक कोड लिख और चला सकते हैं और तुरंत एआई प्रतिक्रिया पा सकते हैं—स्थानीय सेटअप की आवश्यकता नहीं है।

इस पाठ्यक्रम के सभी पाठ

  1. मेटाटेबल का परिचय
  2. __index और __newindex
  3. अंकगणितीय मेटामेथड
  4. __tostring और __len
← Lua Academy पर वापस जाएँ