systemdebt
systemdebt

Reputation: 4941

Meta tables in lua and_index function

__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

Answers (1)

W.B.
W.B.

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

Related Questions