Search code examples
luadrawmetatable

Ignoring metatable in Lua?


I'm working on a Lua menu, and I got Menu class which creates instances like this:

function Menu:new(label, action, open)
    local inst = {
        parent = self,
        label = label,
        action = action,
        open = open or self.defaultOpenState,
        current = false
    }
    setmetatable( inst, { __index = self } )
    if self.subMenus then
        table.insert( self.subMenus, inst )
    else
        self.subMenus = { inst }
    end
    return inst
end

That's not all the code obviously for the menu, but that's enough to explain my problem. The menu is working just fine, how ever, printing it isn't. Problem is, I'm using recursive method to print out all the submenus, but it keeps on printing the very first menu over and over again. I know what causes it, but not sure how to fix it. Here's the code:

function Menu:draw(indent)
    local indent = indent or 0
    if self.label then
        if self.current then
            print( string.rep( "    ", indent ) .. self:getDirectoryMark() .. "<" .. self.label .. ">" )
        else
            print( string.rep( "    ", indent ) .. self:getDirectoryMark() .. " " .. self.label )
        end
    end
    if self.subMenus and self.open then
        for k, v in ipairs( self.subMenus ) do
            v:draw( indent + 1 )
        end
    end
end

And the problem is (I suppose it is, correct me if I'm wrong?), that on line 10 if self.subMenus ... it is always true. There's always a subMenu, even if there wasn't, since the menu (self) doesn't find a submenu, it checks for it's metatable, which has subMenu, and then on line 11, it does the for loop for it's metatables submenus. Which means, it'll draw itself again. And again. And again. So is there a way to bypass a metatable, in just one place? Or am I even right, is the repeated printing caused by that?


Solution

  • Use rawget(table, index).