From eacf0f60c0752616407fbca6cd9d8ca9757ce624 Mon Sep 17 00:00:00 2001 From: Aki Date: Wed, 5 Jul 2017 16:52:50 +0200 Subject: Initial commit --- Object.lua | 83 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 Object.lua (limited to 'Object.lua') diff --git a/Object.lua b/Object.lua new file mode 100644 index 0000000..9b9080b --- /dev/null +++ b/Object.lua @@ -0,0 +1,83 @@ +local extends + +--- Metatable used for each class created. +-- `__call` is an instance constructor. +-- `__index` and `_index` are used when accessing variables inside of class and its hierarchy when accessing class itself. +local metaclass do + local function _index (self, key) + local super = rawget(self, "__super") + if super then + local value = rawget(super, key) + if value ~= nil then + return value + end + return _index(super, key) + end + end + metaclass = { + __index = function (self, key) + if key == "extends" then + return extends + end + return _index(self, key) + end, + __call = function (self, ...) + local o = setmetatable({}, self) + self.new(o, ...) + return o + end + } +end + +--- Method for checking if instance is of selected class. +-- Usage: `instance:is(Object)`. +-- Also works with classes: `Object:is(Object)`. +local is do + local function _is (self, class) + if self then + if self == class then + return true + end + return _is(rawget(self, "__super"), class) + end + end + function is (self, class) + local mt = getmetatable(self) + if mt ~= metaclass then + return _is(mt, class) + end + return _is(self, class) + end +end + +--- Indexing metamethod for instances. +local index do + local function _index (self, key) + if self then + local value = rawget(self, key) + if value ~= nil then + return value + end + return _index(rawget(self, "__super"), key) + end + end + function index (self, key) + return _index(getmetatable(self), key) + end +end + +--- Class creation/extension function. +-- Class table is used as metatable for instance of that class. `Metaclass` table is used as metatable for classes. +function extends (parent) + local self = setmetatable({}, metaclass) + rawset(self, "__class", self) + rawset(self, "__index", index) + rawset(self, "__super", parent) + return self +end + +--- Base class used as root for class hierarchy. +local Object = extends(nil) +rawset(Object, "new", function () end) +rawset(Object, "is", is) +return Object -- cgit v1.1