I have been working at creating a more Object oriented approach to function calls, and I put together this generic object class which can be used to generate subclasses with inheritance from their parent classes. This class comes with internal methods copy(),length(),contains(),keys() and concat(). I am going to add other methods and sub classes as well, but this is what I created so far.
local Test = {"some","test",{"data"},Last = true}
Object:new(Test):keys():concat()
– returns list of keys
Object:new(Test):length()
– returns 4
Object:new(Test):contains("data")
– returns true (deep comparison)
Object:new(Test):copy()
– returns object (deep copy)
Sub classes can also be created by passing a table to the Object.new() call and then calling the :new method from the variable returned from the former call. The class will have this new passed table as it’s metatable as well as inheritance of methods from its super class.
Object = {new = false}
------------------------------------------------------------------
-- Primative Object Constructor
------------------------------------------------------------------
function Object:new(obj) -- Generic object constructor
local valid = obj and type(obj) == "table"
local Instance = valid and obj or {}
setmetatable(Instance,{__index = self})
return Instance
end
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----
-- Returns the number of elements in an object
function Object:length()
local length = 0 for _,_ in pairs(self) do length = length + 1 end
return length -- Return: "number"
end
-- Returs array object of keys in an object
function Object:keys()
local keys = Object:new() for Key,_ in pairs(self) do keys[#keys + 1] = toString(Key) end
return keys -- Return: "array object"
end
-- Returns true if element exists in object
function Object:contains(element)
local function Sub_Scan(entry) -- Sub Level Value Comparison
for _,value in pairs(entry) do
if value == element then return true
elseif type(value) == "table" then
if Sub_Scan(value) then return true
end end end end
local function Scan() -- Top Level Value Comparison
for _,value in pairs(self) do
if value == element then return true
elseif type(value) == "table" then
if Sub_Scan(value) then return true end end end
return false end
return(Scan()) -- Return: "boolean"
end
-- Returns a deep copy of an object (elements and metatables)
function Object:copy()
local Clone = {} -- Initial copy container
local function Sub_Copy(source,target) -- Sub level value copy
for key,value in pairs(source) do
if type(value) ~= "table" then target[key] = value
else target[key] = {} setmetatable(target[key],getmetatable(source[key]))
Sub_Copy(source[key],target[key]) end end end
local function Copy() -- Top Level value copy
for key,value in pairs(self) do
if type(value) ~= "table" then Clone[key] = value
else Clone[key] = {} setmetatable(Clone[key],getmetatable(self[key]))
Sub_Copy(self[key],Clone[key]) end end
setmetatable(Clone,getmetatable(self))
return Clone end
return(Copy()) -- Return: "object"
end
-- Returns concantenated string of array entries
function Object:concat(sep) -- Return: "string"
if self:length() ~= #self then error("Object.concat only operates on arrays.") end
return table.concat(self,sep)
end
---- ---- ---- ---- ---- ---- ---- ---- ---- ---- ----