clasp - tiny class library

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: clasp - 13 lines of class

Post by airstruck »

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.
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: clasp - 13 lines of class

Post by evölbug »

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 :(
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: clasp - 13 lines of class

Post by evölbug »

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
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: clasp - 13 lines of class

Post by evölbug »

i'm choosing ease of debugging versus whatever that fractal of headache is
fractal.png
fractal.png (52.05 KiB) Viewed 5921 times
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: clasp - 13 lines of class

Post by airstruck »

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.
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: clasp - 13 lines of class

Post by evölbug »

it's the same as my code just spread out, and it still makes fractals when removing self.__meta = nil on line 2
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: clasp - 13 lines of class

Post by airstruck »

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.
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: clasp - 13 lines of class

Post by evölbug »

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
User avatar
evölbug
Prole
Posts: 38
Joined: Wed Dec 21, 2016 12:58 pm
Contact:

Re: clasp - 13 lines of class

Post by evölbug »

though your spread out approach inspired a more compact solution i have arrived at now
User avatar
airstruck
Party member
Posts: 650
Joined: Thu Jun 04, 2015 7:11 pm
Location: Not being time thief.

Re: clasp - 8 lines of class

Post by airstruck »

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.
Post Reply

Who is online

Users browsing this forum: No registered users and 45 guests