lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]




On 08/11/15 09:12 PM, Andrew Starks wrote:
On Sun, Nov 8, 2015 at 2:42 PM, Marco Atzori
<marco.atzori.1983@gmail.com> wrote:
Can I set a different index in metatable? Something like this

local mt = { __index =
   { insert = function(t,pos,value) table.insert(t,pos, value) end},
   { remove = function(t,pos) table.remove(t,pos) end}
}

If yes, what would be the correct way?

You have it, i think. The best place to study is:
http://www.lua.org/manual/5.3/manual.html#2.4

In short, You need a metatable with the __index metamethod defined. If
you set that field to a table, then Lua will look at that table as a
back up, such that these two lines of Lua will do the same thing:

```
x = setmetatable({}, {
     __index = table
})

x = setmetatable({}, {
     __index = function(self, i)
         return rawget(table, i)
     end
})
```

Notice that in the second example, i used rawget. Lua does rawget when
you use the first method. This was a design choice and the reverse can
be done by just replacing the return line with `return table[i]`.
Since when?!

So...

```
t = {}
-- I create a table and I set the __index field to a table that I want
to use as a fall back.
setmetatable(t, {__index = table})
table: 0x7fdb52403870

-- Now, whenever a *missing* index is accessed, this table is tried.
assert(t.remove)
function: 0x10338b2a0
assert(t.insert)
function: 0x10338b030
---however, pairs will not see these values, because pairs only sees
the indexes that are actually in the table. In order to change that
behavior, you need to define __pairs
for index, value in pairs(t) do print("Index:",index, "value:", value) end
--nothing returned

--- Also, if I set an index on the table, I'll be setting it on `t`,
only. In order to change the way that *setting* indexes works, but
only on indexes where the table's index is nil.
t.insert = false
for index, value in pairs(t) do print("Index:",index, "value:", value) end
Index: insert value: false

-- let's look at table and print out its values....
for index, value in pairs(table) do print("Index:",index, "value:", value) end
Index: insert value: function: 0x10338b030
Index: pack value: function: 0x10338b130
--...snip
--- Notice how insert is untouched?
```

-Andrew


--
Disclaimer: these emails may be made public at any given time, with or without reason. If you don't agree with this, DO NOT REPLY.