## clasp - tiny class library

airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

### Re: clasp - 13 lines of class

You're right, I just tried it. Also noticed __meta still appears in the dump even after nilling it (with all three methods); something's off.

evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

### Re: clasp - 13 lines of class

well, from the end user perspective it makes no difference functionally, perhaps i can make it use reference instead. it's just that i don't like recursing stuff as it opens the potential to be incredibly hard to debug.

though metatables are hard to debug in general, and i've also noticed it doesn't override metamethods when inheriting, oh no

evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

### Re: clasp - 13 lines of class

so i have discovered that nilling the __meta table is not a good idea, in any cases, so now it's a matter of choosing that little bit of performance at the risk of being potentially harder to debug, or cleanliness

evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

### Re: clasp - 13 lines of class

i'm choosing ease of debugging versus whatever that fractal of headache is
fractal.png (52.05 KiB) Viewed 1827 times

airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

### Re: clasp - 13 lines of class

Here's what I came up with, I've got to run but take a look:

Code: Select all

local function new (self, ...)
local meta = self.__meta or {}; meta.__index = self; self.__meta = nil
local object = setmetatable({}, meta)
return object.init and object:init(...) and object or object
end

local function extend (base, members)
return setmetatable(members, { __index = base, __call = new })
end

return function (members)
return extend(members or {}, { new = new, extend = extend })
end
About nilling __meta, it doesn't always do anything because it might be getting it from __index (with inheritance). Also why rawget didn't work. It would be nice if you could put metamethods directly in class definition instead of in __meta, that way subclass can override one metamethod while leaving others intact.

evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

### Re: clasp - 13 lines of class

it's the same as my code just spread out, and it still makes fractals when removing self.__meta = nil on line 2

airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

### Re: clasp - 13 lines of class

evölbug wrote:it's the same as my code just spread out
That was the point, still 13 lines but without redefining functions each time, also easier to follow I think.
it still makes fractals when removing self.__meta = nil on line 2
It gives an almost identical result to the "pairs" code when you don't remove that, though, doesn't it? But as you said I don't think there's any harm in leaving it there.

evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

### Re: clasp - 13 lines of class

well, it doesn't generate almost identical code, because you can't override individual methods without overriding whole __meta table, and also it generates fractals if you don't nil the table

evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

### Re: clasp - 13 lines of class

though your spread out approach inspired a more compact solution i have arrived at now

airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

### Re: clasp - 8 lines of class

Yeah, I see what you mean about overriding individual metamethods. I guess you'll need to copy these no matter what if they're supposed to be inherited. Here's an idea for moving it from instantiation to declaration:

Code: Select all

local function new (class, ...)
local object = setmetatable({}, class)
return object, object:init(...)
end

local function extend (class, proto)
for k, v in pairs(class) do
if k:match '^__' and proto[k] == nil then proto[k] = v end
end
proto.__index = proto
return setmetatable(proto, class)
end

local base = { __call = new, new = new, extend = extend, init = function()end }
base.__index = base

return function (proto)
return extend(base, proto)
end
This also lets you put your metamethods right in the class definition instead of a separate table. It will create lots of circular references from metatables being their own index, so the dump will be ugly. Can have dump function leave out cycles to get a better look; cycles in the dump are probably nothing to worry about.

Also has weird side effect that instances can themselves be extended and instantiated, but this could actually be pretty useful and sort of makes sense for prototype-based inheritance.

### Who is online

Users browsing this forum: No registered users and 2 guests