Refactor OOP implementation: replace class-based structure with a function-based approach and enhance method definitions

This commit is contained in:
Chipperfluff 2026-01-01 17:14:23 +01:00
parent c0c37059d6
commit b32a9d8786
2 changed files with 135 additions and 15 deletions

View File

@ -1,12 +1,16 @@
utils = require("oop/utils") oop = require("oop/oop")
class = { local function MyClass(cls)
name = "MyClass", cls.setattr(cls, "name")
sayHello = function(self)
print("Hello from " .. self.name) function cls.__init(this, name)
this.name = name
end end
}
obj = utils.deepcopy(class) function cls.test(this, name)
obj.name = "Carl" print("hi " .. this.name .. " from " .. name)
obj.sayHello(obj) -- Output: Hello from Carl end
end
local obj = oop.new(MyClass, "Carl")
obj.test("tom") -- Output: hi Carl from tom

View File

@ -1,9 +1,125 @@
--[[ local oop = {}
the plan is to create a simple oop system in lua
it might not work liky python local function super_call(self, method_name, ...)
local class = getmetatable(self)
if not class then
error("super() called on non-instance")
end
local base = rawget(class, "__base")
if not base then
error("super() called but no base class")
end
local fn = base[method_name]
if not fn then
error("base class has no method '" .. tostring(method_name) .. "'")
end
return fn(self, ...)
end
think of it more like a facory system local function_def_cache = setmetatable({}, { __mode = "k" })
with at least the concept of self
]]
function oop.setattr(target, key, value)
target[key] = value
end
function oop.new(class, ...)
local actual_class = class
if type(class) == "function" then
actual_class = function_def_cache[class]
if not actual_class then
actual_class = oop.class(class)
function_def_cache[class] = actual_class
end
end
local obj = setmetatable({}, actual_class)
if actual_class.__init then
actual_class.__init(obj, ...)
end
return obj
end
local function lookup_in_class(cls, key)
local cur = cls
while cur do
local val = rawget(cur, key)
if val ~= nil then
return val
end
cur = rawget(cur, "__base")
end
return nil
end
function oop.class(def, base)
local cls = {}
cls.__name = "Anonymous"
cls.__base = base
cls.__index = function(self, key)
local val = lookup_in_class(cls, key)
if type(val) == "function" then
return function(...)
return val(self, ...)
end
end
return val
end
function cls:super(method_name, ...)
return super_call(self, method_name, ...)
end
function cls.setattr(target, key, value)
return oop.setattr(target, key, value)
end
setmetatable(cls, {
__index = base,
__call = function(c, ...)
return oop.new(c, ...)
end
})
if type(def) == "string" then
cls.__name = def
elseif type(def) == "function" then
def(cls)
elseif def ~= nil then
error("class definition must be a function or name string")
end
return cls
end
function oop.isinstance(obj, class)
local mt = getmetatable(obj)
while mt do
if mt == class then
return true
end
mt = rawget(mt, "__base")
end
return false
end
function oop.issubclass(class, base)
local mt = class
while mt do
if mt == base then
return true
end
mt = rawget(mt, "__base")
end
return false
end
function oop.install(env)
local target = env or _G
target.class = oop.class
target.new = oop.new
target.setattr = oop.setattr
target.isinstance = oop.isinstance
target.issubclass = oop.issubclass
end
oop.install()
return oop