लुआ में कक्षाएं, या बृहदान्त्र से छुटकारा

जैसा कि सभी जानते हैं, लुआ में ऐसी कोई कक्षाएं और वस्तुएं नहीं हैं। हालांकि, मेटाटैबल्स और सिंटैक्टिक शुगर हैं।
इन तंत्रों का उपयोग करते हुए, यह वर्ग समानता को लागू करने के लिए पर्याप्त सरल है।
परिणाम कुछ इस प्रकार है:
सबसे सरल वर्ग
local MyClass = {} -- the table representing the class, which will double as the metatable for the instances MyClass.__index = MyClass -- failed table lookups on the instances should fallback to the class table, to get methods -- syntax equivalent to "MyClass.new = function..." function MyClass.new(init) local self = setmetatable({}, MyClass) self.value = init return self end function MyClass.set_value(self, newval) self.value = newval end function MyClass.get_value(self) return self.value end local i = MyClass.new(5) -- tbl:name(arg) is a shortcut for tbl.name(tbl, arg), except tbl is evaluated only once print(i:get_value()) --> 5 i:set_value(6) print(i:get_value()) --> 6 

( lua-users.org/wiki/ObjectOrientationTutorial से लिया गया)

यह सब निश्चित रूप से अच्छा है, यहां तक ​​कि एक निश्चित निपुणता के साथ, विरासत का एहसास किया जा सकता है ...
लेकिन सार्वजनिक और निजी वर्ग के सदस्य कहाँ हैं? वास्तव में, इस उदाहरण में वे सभी सार्वजनिक हैं। हां, और हमें याद रखना चाहिए कि कोलन का उपयोग कहां करना है:
 MyClass:myFunc() 

और जहां सिर्फ एक बिंदु है:
 MyClass.myOtherFunc() 

और वर्ग के स्थिर सदस्य? वास्तव में मना करना है?


इसलिए मैं मना नहीं करना चाहता था, और सामूहिक खेती करने लगा ...

इसलिए, मैं आपको अपने सामूहिक खेत में प्रस्तुत करता हूं:
मेरा सामूहिक खेत
 createClass = function() local creator = {} creator.__private = { object_class = {}, } creator.__oncall = function(class_creator) -- Get the class definition so we can make needed variables private, static, etc. local this = class_creator() -- Initialize class from class definition __init = function() -- Init Public Static local class = {} if (type(this.__public_static) == "table") then class = this.__public_static end -- Init Object local thisClass = this local __constructor = function(...) local object = {} local this = class_creator() -- Init Public if (type(this.__public) == "table") then object = this.__public end -- Init static values of the class this.__public_static = thisClass.__public_static this.__private_static = thisClass.__private_static -- Call Constructor if (type(this.__construct) == "function") then this.__construct(...) end -- Returning constructed object return object end return {class = class, constructor = __constructor} end -- Creating class (returning constructor) local class_data = __init() local class = class_data.class local constructor = class_data.constructor -- Set class metatable (with setting constructor) local class_metatable = { __newindex = function(t, key, value) if type(t[key])=="nil" or type(t[key])=="function" then error("Attempt to redefine class") end rawset(t, key, value) end, __metatable = false, __call = function(t, ...) if type(t) == nil then error("Class object create failed!") end local obj = constructor(...) creator.__private.object_class[obj] = t local object_metatable = { __newindex = function(t, key, value) class = creator.__private.object_class[t] if type(class[key])~="nil" and type(class[key])~="function" then rawset(class, key, value) return end if type(t[key])~="nil" and type(t[key])~="function" then rawset(t, key, value) return end error("Attempt to redefine object") end, __index = t, __metatable = false, } setmetatable(obj, object_metatable) return obj end, } -- Setting class metatable to the class itself setmetatable(class, class_metatable) -- Returning resulting class return class end return creator.__oncall end createClass = createClass() 



और इसका उपयोग कैसे करें? बहुत सरल है, यहाँ आपके लिए एक टेम्प्लेट है:
 myclass_prototype = function() local this = {} this.__public_static = { -- Public Static Variables statvalue = 5, -- Public Static Funcs statfunc = function() print(this.__public_static.statvalue) end, } this.__private_static = { -- Private Static Variables privstatdat = 2, -- Private Static Funcs privstatfunc = function() print(this.__private_static.privstatdat) end, } this.__public = { -- Public Variables pubdata = 3, -- Public Funcs pubfunc = function(newprivate) print(this.__public.pubdata) this.__private.privdata = newprivate end, } this.__private = { -- Private Variables privdata = 1, -- Private Funcs listallprivate = function() print(this.__private.privdata) end, } this.__construct = function() -- Constructor end return this end myclass=createClass(myclass_prototype) 

जैसा कि आप देख सकते हैं, हर बार जब आप कक्षा के अंदर से कॉल करते हैं, तो आपको हर बार पथ निर्दिष्ट करना होगा, लेकिन ".__ Private.privdata" के लिए, लेकिन यहां बनाई गई कक्षा का उपयोग करने का एक उदाहरण है!
 myobject = myclass() myobject.pubfunc(999) 

जब यह कोड कहा जाता है, तो मायक्लास क्लास से myobject ऑब्जेक्ट बनाया जाएगा, और pubfunc फ़ंक्शन को बुलाया जाएगा, जो सार्वजनिक चर की सामग्री को उजागर करेगा और निजी को बदल देगा।
और कोलोन के साथ कोई परेशानी नहीं!
वैसे, स्टैटिक कॉल्स भी काम करती हैं। दोनों वर्ग से और वस्तु से।

इसलिए, मैं आपको संक्षेप में बताऊंगा कि यहां किस तरह का जादू होता है। और तथाकथित उत्थानों के साथ यहाँ बाजीगरी है। upvalues ​​वैरिएबल होते हैं जो अंदर से तो दिखाई देते हैं, लेकिन बाहर से नहीं! बहुत निजी के समान, है ना?
इसलिए, "प्रोटोटाइप" फ़ंक्शन बनाने के बाद, हमने एक नया स्कोप बनाया, और हमने अपनी क्लास के सभी अंदरूनी हिस्सों को इसमें रखा, केवल क्लास के पब्लिक और पब्लिक स्टैटिक सदस्यों को बाहर निकाला। और बाकी का जादू मेटाटैबल्स द्वारा किया जाता है जो आपको यह निर्धारित करने की अनुमति देता है कि जब आप हमारी कक्षा / वस्तु का प्रतिनिधित्व करते हैं तो बाहरी तालिका के "गैर-प्रासंगिक" सदस्य से अनुरोध करने पर वास्तव में क्या होगा।
अराजक लगता है, मुझे पता है, लेकिन मैं बेहतर नहीं समझा सकता हूँ - विशेष नहीं :)

मैंने लंबे समय से सोचा था कि इस तरह की प्रणाली के साथ विरासत कैसे बनाई जाए, लेकिन मैं इसके साथ कभी नहीं आया - upvalues ​​गंभीरता से हमारे कार्यों को प्रतिबंधित करता है, और मैं डिबग लाइब्रेरी जैसे विकृतियों का उपयोग नहीं करना चाहता हूं - यह हमेशा शामिल नहीं है। अगर कोई ऐसा सोचता है, तो मुझे खुशी होगी!

पुनश्च: अगर किसी के लिए मेरी पोस्ट कुछ स्पष्ट है - ठीक है, तो मैंने खुद को बहुत कम आंका है :) कड़ाई से न्याय न करें, शायद किसी कारण से यह समाधान काम आएगा!

Source: https://habr.com/ru/post/In182018/


All Articles