With the introduction of the function type()
it is now possible to know the type of the variable.
So I tried to find a way to implement a simple class system and I think I found a way
First we need a function to copy tables
function copy(o) local c if type(o) == 'table' then c = {} for k, v in pairs(o) do c[k] = copy(v) end else c = o end return c end |
then we can declare our objects the following way:
vec = {} vec.x = 0 vec.y = 0 function vec:add(v) self.x += v.x self.y += v.y end function vec:subs(v) self.x -= v.x self.y -= v.y end function vec:mult(c) self.x *= c self.y *= c end |
to create multiple instances of vector, we just need to copy the object and edit it's attributes
a = copy(vec) b = copy(vec) a.x = 1 a.y = 2 b.x = 3 b.y = -1 |
and when we call the a:add(b) we get a.x == 4, a.y == 1
what's more we can define "subclass"
vec3 = copy(vec) vec3.z = 0 function vec3:printz() print(self.z) end |
the function printz() will run just fine on copies of vec3 but will return an error on copies of vec
I like how type() can make your recursive copy() concise and reusable for prototypes with table values. It's otherwise not difficult to shallow-copy method references within a constructor. Create an empty object for the prototype class, assign methods with method syntax, then define a constructor (e.g. vec:new()) that copies method references with a simple loop over attributes and assigns initial member values (including fresh copies of table values, as needed).
(I don't know how many existing carts bother to do this. A while back I searched through 900+ carts for uses of "self" and the method syntax, only a small percentage did, and the few that I looked at didn't reuse method code in memory and instead just created a new closure per method per instance.)
If I understand correctly, we won't have real prototypical inheritance until we can access an object's metatable (getmetatable, setmetatable; metamethods like self.__index). Of course, we could write an arbitrarily complex method dispatch system if we forego Lua method syntax (instead using something like a call("method", ...) method). Language support for OO will be more relevant once we have a library reuse mechanism.
[Please log in to post a comment]