lua-users home
lua-l archive

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


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]`.

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