local Obj = {} function Obj.spam() print 'Hello world' end --[[ : local Obj = { spam = function() print 'Hello world' end, } ]] Obj.spam() -- Hello world
local Obj = {} function Obj.spam(self) print(self) end Obj.spam(Obj)
local Obj = {} function Obj.spam(self) print(self) end function Obj:spam2() print(self) end Obj:spam() -- Obj['spam'](Obj), .. , , , . Obj:spam2() Obj.spam(Obj) -- table: 0x417c7d58 -- table: 0x417c7d58 -- table: 0x417c7d58
local Obj = { var = 0, } function Obj:new(val) self:set(val or 0) return self end function Obj:set(val) self.var = val end function Obj:print() print(self.var) end local a = Obj:new(42) a:print() local b = Obj:new(100500) b:print() a:print() -- 42 -- 100500 -- 100500
local Obj = { var = 0, } function Obj:set(val) self.var = val end function Obj:print() print(self.var) end function Obj:new(val) -- local inst = {} -- , Obj for k, v in pairs(self) do inst[k] = v end inst.new = nil -- . :) inst:set(val or 0) return inst end local a = Obj:new(42) a:print() local b = Obj:new(100500) b:print() a:print() -- 42 -- 100500 -- 42
local mt = { __add = function(op1, op2) local op1 = type(op1) == 'table' and op1.val or op1 local op2 = type(op2) == 'table' and op2.val or op2 return op1 + op2 end, __tostring = function(self) return tostring(self.val) end, } local T = { val = 0, new = function(self) local inst = {} for k, v in pairs(self) do inst[k] = v end -- , setmetatable(inst, getmetatable(self)) return inst end, } setmetatable(T, mt) local a = T:new() a.val = 2 local b = T:new() b.val = 3 print(a) print(b) print(a + b) print(a + 10) print(100 + b) -- 2 -- 3 -- 5 -- 12 -- 103
local T = {} local T_mt = { __index = T, -- , } function T.create() -- setmetatable return setmetatable({}, T_mt) end function T:set(val) self.val = val or 0 end function T:print() print(self.val) end local a = T.create() a:set(42) local b = T.create() b:set(100500) a:print() b:print() a:print() -- a.foo = 7 print(a.foo) print(b.foo) -- T.bar = 7 print(a.bar) print(b.bar)
getmetatable(a).__index.print(a)
local T = {} setmetatable(T, { __call = function(cls) return cls.create() end, }) -- ! T.create() T(): local a = T() local b = T()
local OOP = {} function OOP.class(struct) -- return cls -- , end -- local A = OOP.class { val = 0, set = function(self, val) self.val = val or 0 end, print = function(self) print(self.val) end, } -- local a = A:create() a:print() a:set(42) a:print()
function OOP.class(struct) local struct = struct or {} local cls = {} local function _create_instance() local inst = {} for k, v in pairs(struct) do inst[k] = v end return inst end setmetatable(cls, { __index = { create = _create_instance, -- , }, __call = function(cls) return cls:create() -- end, }) return cls end
-- ... local function _create_instance() local inst = {} -- ... inst.__class = cls -- ... end -- ... A.clsMeth = function(cls) print('Hello') end -- ... a.__class:clsMeth() -- a.clsMeth()
-- . function OOP.subclass(parent) return function(struct) return OOP.class(struct, parent) end end local A = OOP.class { -- ... } local B = OOP.subclass(A) { -- B A welcome = function(self) print('Welcome!') self:print() -- end, } local b = B() b:print() b:set(100500) b:welcome()
function OOP.class(struct, parent) -- 1. local struct = struct or {} local cls = {} local function _create_instance() local base = parent and parent:create() or nil -- 2. local inst = {} -- 3. if base then for k, v in pairs(base) do inst[k] = v end end for k, v in pairs(struct) do inst[k] = v end inst.__class = cls return inst end setmetatable(cls, { __index = setmetatable( -- 4. { create = _create_instance, }, { -- , __index = function(_, key) if parent then return parent[key] end end, } ), __call = function(cls) return cls:create() end, }) return cls end
-- ... setmetatable(cls, { -- ... __call = function(cls, ...) local inst = cls:create() -- - local new = inst.new if new then new(inst, ...) end return inst end, }) -- ... local A = OOP.class { new = function(self, text) text = text or '' print('Hello ' .. text) end, } local B = OOP.subclass(A) { } A('world') B('traveler') -- Hello world -- Hello traveler
local B = OOP.subclass(A) { new = function(self, text) print('B says ' .. tostring(text)) end, } B('spam')
local B = OOP.subclass(A) { new = function(self, text) print('B says ' .. tostring(text)) self:super('from B') end, } -- ... local function super_func(self, ...) local frame = debug.getinfo(2) local mt = getmetatable(self) assert(mt and mt.__base, 'There are no super method') local func = mt.__base[frame.name] return func and func(self, ...) or nil end -- ... local function _create_instance() -- ... -- inst.super , . -- /. -- pairs(struct), . a.super = x . local inst = setmetatable({}, { __base = base, __index = { super = super_func, }, }) -- ...
local A = OOP.class((function() -- local function private(self, txt) print('Hello from ' .. txt) end return { val = 0, public = function(self) private(self, 'public') end, } end)())
Source: https://habr.com/ru/post/228001/
All Articles