Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inheritance for metamethods in Lua

i very much like how object oriented programming is described in "programming in lua" 16.1, 16.2:

http://www.lua.org/pil/16.1.html

http://www.lua.org/pil/16.2.html

and would like to follow this approach. but i would like to take things a little further: i would like to have a base "class" called "class", which should be the base of all subclasses, because i want to implement some helper methods there (like "instanceof" etc.), but essentially it should be as described in the book:

function class:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    return o
end

now to my problem:

i would like to have a class "number", which inherits from "class":

number = class:new()

i would like to define metamethods for operator overloading (__add, __sub, etc.) in this class, so something like:

n1 = number:new()
n2 = number:new()

print(n1 + n2)

works. this is not really a problem. but now i would like to have a third class "money", which inherits from "number":

money = number:new{value=10,currency='EUR'}

i introduce some new properties here and such.

now my problem is, that i don't get things to work, that "money" inherits all methods from "class" and "number" including all metamethods defined in "number".

i've tried several things like overwriting "new" or modifying metatables but i was not able to get things to work, without either loosing the methods of "class" in "money" or loosing the metamethods of "number" in "money"

i know, that there a lot's of class implementations out there, but i would really like to stick with the minimal approach of lua itself.

any help would be very much appreciated!

thanks very much!

like image 816
aurora Avatar asked Nov 11 '10 15:11

aurora


People also ask

What is __ index in Lua?

When Lua detects that w does not have the requested field, but has a metatable with an __index field, Lua calls this __index metamethod, with arguments w (the table) and "width" (the absent key). The metamethod then indexes the prototype with the given key and returns the result.

Can you create classes in Lua?

Lua does not have the concept of class; each object defines its own behavior and has a shape of its own. Nevertheless, it is not difficult to emulate classes in Lua, following the lead from prototype-based languages, such as Self and NewtonScript. In those languages, objects have no classes.

Does Lua have polymorphism?

Polymorphism is where a function acts differently depending on what it's acting on. Due to Lua's loose type checking, a lot of the polymorphism you need in C++ or Java just to get around their ubiquitous type checking is unnecessary. The rest can be done with metatables and is beyond the scope of this web page.


1 Answers

I think that the problem you are having is due to the fact the the operator metamethods are looked up using something similar to rawget(getmetatable(obj) or {}, "__add"). Thus the operators are not inherited with along with the other functions.

I have had some success with having the new function copy the operators like this:

function class:new(o)
    o = o or {}
    setmetatable(o, self)
    self.__index = self
    local m=getmetatable(self)
    if m then
        for k,v in pairs(m) do
            if not rawget(self,k) and k:match("^__") then
                self[k] = m[k]
            end
        end
    end
    return o
end
like image 50
gwell Avatar answered Nov 09 '22 22:11

gwell