tags:

views:

490

answers:

2

how do you make a default table and then use it when making other tables?

example

--default table
Button = {
 x = 0,
 y = 0,
 w = 10,
 h = 10,
 Texture = "buttonimg.png",
 onClick = function() end
}

newbutton = Button {
 onClick = function()
  print("button 1 pressed")
 end
}


newbutton2 = Button {
 x = 12,
 onClick = function()
  print("button 2 pressed")
 end
}

newbuttons will get y, w, h and texture set to default value but anything set in the brackets get overwritten

A: 

If you set the new table's metatable's __index to point to Button it will use the default values from the Button table.

--default table
Button = {
 x = 0,
 y = 0,
 w = 10,
 h = 10,
 Texture = "buttonimg.png",
 onClick = function() end
}

function newButton () return setmetatable({},{__index=Button}) end

Now when you make buttons with newButton() they use the default values from the Button table.

This technique can be used for class or prototype object oriented programming. There are many examples here.

Doug Currie
The brackets around __index are superfluous.
David Hanak
Thanks, David; I copied the wrong text from my shell. Fixed.
Doug Currie
+2  A: 

You can achieve what you want by merging Doug's answer with your original scenario, like this:

Button = {
   x = 0,
   y = 0,
   w = 10,
   h = 10,
   Texture = "buttonimg.png",
   onClick = function() end
}
setmetatable(Button,
         { __call = function(self, init)
                       return setmetatable(init or {}, { __index = Button })
                    end })

newbutton = Button {
   onClick = function()
                print("button 1 pressed")
             end
}

newbutton2 = Button {
   x = 12,
   onClick = function()
                print("button 2 pressed")
             end
}

(I actually tested this, it works.)

Edit: You can make this a bit prettier and reusable like this:

function prototype(class)
   return setmetatable(class, 
             { __call = function(self, init)
                           return setmetatable(init or {},
                                               { __index = class })
                        end })
end

Button = prototype {
   x = 0,
   y = 0,
   w = 10,
   h = 10,
   Texture = "buttonimg.png",
   onClick = function() end
}

...
David Hanak