ClosureClass

Showcase your libraries, tools and other projects that help your fellow love users.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: ClosureClass

Post by BlackBulletIV »

kikito wrote:
BlackBulletIV wrote:Indeed, this is one big problem with closures, instances won't respond if you modify the class, which is a shame.
Are you sure this is a problem due to closure usage? My gut tells me there must be a way to implement indirection with them too.
BlackBulletIV wrote:I'm not sure what you're talking about by copying methods directly to instances. If you're talking about the code the copies stuff from superclass to subclass, that's for inheriting class methods and attributes (and also modules).
I was talking about this code inside _new (pasting below for reference)

Code: Select all

for _, m in pairs(cls.__modules) do
    for name, func in pairs(m) do
      if name ~= 'included' then
        self[name] = function(...) return func(self, ...) end -- get rid of self for the outside world
      end
    end
  end
I'm not sure of what it does - maybe getting rid of the need of using : instead of . ? But then, why doing that only with module methods?
BlackBulletIV wrote:I'm guessing metamethods are copied, I'm not quite sure how it works in MiddleClass (don't you just define an instance function). Anyway, metamethods are yet to be handled.
Metamethods are a bit of a pain on lua when dealing with inheritance. The problem is that Lua doesn't want to use metatables in order to get metamethods: a table must have a __tostring metamethod on its metatable; if its "parent" (the metatable pointed by __index) has a __tostring, Lua doesn't care.

On middleclass I handle this by creating a set of "default metamethods" on every new class. These methods "point" to the methods on the superclass. And if there's no parent, they throw an error, just like a regular method would.
I'm sure there is a way, but it would most likely involve some hardcore table trickery, which I'd have to rack my brain for awhile to figure out.

Oh that code copies module functions from the class into the instance. To maintain consistency it wraps the functions to remove the need of a self parameter. As explained in the recently added README, module functions must have a self parameter because they're not declared inside the initialisation function (the closure), therefore they need a reference to self.

Hmmmm, not quite sure whether I totally understand what you're talking about with metamethods. But I have seen how you make a default implementation which throws an error. But anyway, metamethods aren't implemented yet, they might be soon.

All in all, I think the closure method is not a very good fit for a full OOP system in Lua. But still, I love the style.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: ClosureClass

Post by bartbes »

You could get the metatable a metatable. Inception.
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: ClosureClass

Post by BlackBulletIV »

Which problem are you referring to by that?
User avatar
tentus
Inner party member
Posts: 1060
Joined: Sun Oct 31, 2010 7:56 pm
Location: Appalachia
Contact:

Re: ClosureClass

Post by tentus »

bartbes wrote:You could get the metatable a metatable. Inception.
I just rewatched that tonight with my younger bro, who missed it when it came out. Enjoyable film.
Kurosuke needs beta testers
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: ClosureClass

Post by BlackBulletIV »

Oh, you're talking about a movie. Ok.
User avatar
bartbes
Sex machine
Posts: 4946
Joined: Fri Aug 29, 2008 10:35 am
Location: The Netherlands
Contact:

Re: ClosureClass

Post by bartbes »

It's a real option though, getting a metatable with an __index metafield set to the parent's metatable.
User avatar
appleide
Party member
Posts: 323
Joined: Fri Jun 27, 2008 2:50 pm

Re: ClosureClass

Post by appleide »

Tangent.
Recently, I've started to use classes implemented by the following code.

Code: Select all

function class(parent)
  local new = {}
  for k, v in pairs(parent or {init=function() end}) do
    new[k] = v
  end
  new.__super, new.__index = parent, new
  return setmetatable(new, {__call = function(t , ...) 
    local instance=setmetatable({__class = new}, new);
    new.init(instance, ...)
    return instance
  end})
end
Child classes are copies of parent classes.
To instantiate a class, simply call it. e.g. local myvector = vector(x, y)
Classes are the instances metatables, so you can write a method class:__add to overload the + operator.

Code: Select all

style = class()

--- Initiates a style instance.
-- @param tags A string of whitespace separated tags.
-- @param styles A table of key-value style attributes. 
function style:init(tags, styles)
  self.tags = sorttags(tags)
  self.styles = {}
  self.owner = nil
  for k, v in pairs(styles) do
    self.styles[k] = v
  end
  self:compute()
end

--- Compute styles. E.g. borderleftwidth and borderwidth
function style:compute()
  local this = self.styles
  -- ...more code... --
end
User avatar
BlackBulletIV
Inner party member
Posts: 1261
Joined: Wed Dec 29, 2010 8:19 pm
Location: Queensland, Australia
Contact:

Re: ClosureClass

Post by BlackBulletIV »

That looks like a largely simplified version of MiddleClass to be (in the result anyway). The big thing it lacks, which I would not like to be without, is mixins.
User avatar
kikito
Inner party member
Posts: 3153
Joined: Sat Oct 03, 2009 5:22 pm
Location: Madrid, Spain
Contact:

Re: ClosureClass

Post by kikito »

Robin wrote:
kikito wrote:Metamethods are a bit of a pain on lua when dealing with inheritance. The problem is that Lua doesn't want to use metatables in order to get metamethods: a table must have a __tostring metamethod on its metatable; if its "parent" (the metatable pointed by __index) has a __tostring, Lua doesn't care.
That is because

Code: Select all

mt.__index = t -- where mt is the metatable of some other table and t is yet another table
is really a shortcut for

Code: Select all

mt.__index = function (table, key) return t[key] end
Thus t is really not a "parent" of whatever uses mt as metatable, it's just a place to get values for missing keys from.
I know that. The problem is that Lua uses something equivalent to rawget(getmetatable(t), '__tostring') instead of using t.__tostring to get a metamethod. They are not "looked up through __index". So the only option left is creating "fake" metamethods that do that extra bit of work.
When I write def I mean function.
Post Reply

Who is online

Users browsing this forum: No registered users and 2 guests