Reputation: 4941
__index = function(tbl, key)
local a = tbl[key]
if a <=0 then a = 0 end
if a > 5 then a = 0 end
return a
end
Book says: Though the preceding code looks very innocent and tries to keep the value of the element in the table within a range, this code will cause problems and circular references. The first line in the function, a = tbl[key], will actually trigger another index function call, and that in turn will invoke another, and so on.
But how is a = tbl[key] calling another index at every call ?
Upvotes: 2
Views: 1317
Reputation: 5525
That is a bit wierd thing to do. Lua triggers __index
metamethod only if it can't find a field in the table. Therefore, using tbl[key]
inside it makes absolutely no sense at all. Unless tbl
is not a table.
Anyhow, if you want to access a table's field from within __index
, use rawget
. That will ensure that no metamethods are called.
EDIT:
Let me explain how __index
lookup works:
Let's assume the table has a metatable with __index
defined.
If Lua can't find the key in the table, it looks for the __index
field in the metatable. It does not look for the key itself. Then, if the __index
is a table, it looks for the key in that table (not the metatable, although it is common to associate the metatable itself with its __index
field). If it is a function, it is invoked with two parameters: table
(initial table, not the metatable) and the key
.
So if the __index
metamethod is called, you can be certain that the initial table does not have that field defined. Therefore, when you try to index it again (as the first argument is the original table that triggered the index lookup), the story begins anew -> Lua can't find the key, it invokes the __index
and so on.
Upvotes: 7