Q:

Lua inheritance override function

I'm fairly new to Lua and I am trying to get a class system to work. What I would like to do it to have a base class which has a bunch of properties and then extend this class for objects such as buttons, textboxes, etc.
The base class will have properties such as x, y, width, height etc and then the other classes will have, say, label or colour or similar.
If I create a function such as render() on the base class, and try to override this function later on, it doesn't seem to work. (Presumably I'm using classes completely wrong!)
Here is a reproduction down example of what I am using:
Base = {}
Base.__index = Base
function Base.create(value)
    local b = {}
    setmetatable(b, Base)
    b.value = value
    return b
end

function Base:render()
    print("I'm the base! : "..self.value)
end

Button = {}
Button.__index = Base

function Button.create(value)
    local b = Base.create(value)
    setmetatable(b, Button)
    return b
end

function Button:render()
    print("I'm a button! : "..self.value)
end

Button.create("TestBtn"):render()

What I would like the Button.create("TestBtn"):render() do is to print I'm a button! : TestBtn however it prints I'm the base! : TestBtn.
Could someone help me to override the original render function with this new one?
Thanks, Will.

A:

The missing detail, as @siffiejoe mentioned and I hinted at, is that as written your Button objects don't know to look in the Button table for methods.
My solution created garbage tables to create that association and so isn't really the best solution but illustrated the point.
@siffiejoe's answer is better in that it more accurately codifies the desired functionality and relationship. It also then requires the extra step of chaining the "class" tables (i.e. setmetatable(Button, Base)).
The key here is the operation of the index metamethod. This is described with code in the lua Reference Manual:
"index": The indexing access table[key].

function gettable_event (table, key)
   local h
   if type(table) == "table" then
     local v = rawget(table, key)
     if v ~= nil then return v end
     h = metatable(table).__index
     if h == nil then return nil end
   else
     h = metatable(table).__index
     if h == nil then
       error(···)
     end
   end
   if type(h) == "function" then
     return (h(table, key))     -- call the handler
   else return h[key]           -- or repeat operation on it
   end
end

