Metamethods and inheritance

classic Classic list List threaded Threaded
3 messages Options
Reply | Threaded
Open this post in threaded view
|

Metamethods and inheritance

Dirk Laurie-2
I have an object with metatable RECORD and several objects which are
specialized RECORDs, with metatables OBJ1, OBJ2 etc. There are certain
methods and metamethods that are common to all RECORDs and others that
are specific to each specialization.

For non-meta methods the situation is easy: OBJ1.__index = RECORD.

However, for metamethods, access is raw. There is no other way except
copying the metamethods from RECORD into OBJ1 etc.

Or is there?

Reply | Threaded
Open this post in threaded view
|

Re: Metamethods and inheritance

Ulrich Schmidt


Am 31.10.2017 um 11:24 schrieb Dirk Laurie:

> I have an object with metatable RECORD and several objects which are
> specialized RECORDs, with metatables OBJ1, OBJ2 etc. There are certain
> methods and metamethods that are common to all RECORDs and others that
> are specific to each specialization.
>
> For non-meta methods the situation is easy: OBJ1.__index = RECORD.
>
> However, for metamethods, access is raw. There is no other way except
> copying the metamethods from RECORD into OBJ1 etc.
>
> Or is there?
>
.__index can be a function instead a pointer to a 2nd table. You can do
what you want in this function. I suggest, you take a look into
middleclass[1] how they do. But "__index"-ing from one table to the next
to the next to the next .... is time consuming, so take care.

[1]: https://github.com/kikito/middleclass

Reply | Threaded
Open this post in threaded view
|

Re: Metamethods and inheritance

Dirk Laurie-2
2017-10-31 13:32 GMT+02:00 Ulrich Schmidt <[hidden email]>:
> I suggest, you take a look into middleclass[1]
> how they do. But "__index"-ing from one table to the next to the next to the
> next .... is time consuming, so take care.
>
> [1]: https://github.com/kikito/middleclass

OK, I have looked, and unless I totally misunderstand the code, the
parent class knows which subclasses it has, and propagates missing
methods into them.

I've designed a different mechanism, but it also involves keeping a
table of subclass metatables.

local metamethod = function(name)
  return function(record,...)
    local mmt = meta[record.tag]
    local mm = assert(mmt and mmt[name],"No metamethod "..name..
      " defined for "..record.tag)
    return mm(record,...)
  end
end

-- metamethods for ~ + - to be supplied per tag
for mm in ("bnot,add,sub"):gmatch"%l+" do
  mm = '__'..mm
  RECORD[mm] = metamethod(mm)
end

`record.tag` is the name used as key in `meta` for the OBJ's.