10

How do I add a method to the table type? I'm trying to write a method that searches through the values of a table. So far I have.

function table:contains(value)
  for _, v in ipairs(self) do
    if v == value then return true end
  end
  return false
end

Yet when I try to do the following.

t = {'four', 'five', 'six'}
t:contains('five')

I get the error.

stdin:1: attempt to call method 'contains' (a nil value)

Any suggestions?

  • Note that `table.contains(t, 'five')` does work. So the question comes down to: What is the difference between `instance:method(...)` and `type.method(instance, ...)`, which was also puzzling me [here](http://stackoverflow.com/q/33052241/1804173). – bluenote10 Oct 11 '15 at 08:33

3 Answers3

9

As was said by others, your t is a simple table, it contains only the following key-value pairs: [1]='four', [2]='five', [3]='six'.

If you want to "extend" the t to be able to access functions from the table module, you have to set a metatable with __index pointing to the table module. I use the following function to access it easily:

function T(t)
    return setmetatable(t, {__index = table})
end

You can then use it as follows (thanks to syntax sugar no parentheses needed):

t = T{'four', 'five', 'six'}
t:insert('seven')
print(t:contains('seven')) --> true
Michal Kottman
  • 16,375
  • 3
  • 47
  • 62
8

There is no single metatable for all tables. Unlike strings and numbers, each table has its own individual metatable.

Just make a free function instead of a "member" function for these kinds of things. Not everything needs to be all OOP with : and such.

Nicol Bolas
  • 449,505
  • 63
  • 781
  • 982
3

You've added a method to the table library but you haven't given any metatable to table t. There is no automatic connection between table and t.

lhf
  • 70,581
  • 9
  • 108
  • 149