Log in to vote

Why is this __index metatable not saving the row correctly? [closed]

Asked by
BlueTaslem 18071 Moderation Voter Administrator Community Moderator Super Administrator
7 years ago

The goal of this code is to make a grid that is infinitely large by creating a new row whenever one is asked for (via the __index metamethod).

When I ask for a row from the board I do get a row, but it doesn't save it -- if I ask for the same row number, I don't get the same row table out.

local board = {};
setmetatable(board, {__index = function(row)
    local t = {};
    board[row] = t;
    return t;

board[0][0] = true;

assert(board[0] == board[0], "inconsistent");
-- This assert fails, so that means board[0] is NOT the
-- same thing as board[0]
-- Why?
assert(board[0][0] == true, "(0, 0) not set");
-- (This one also fails, for the same reason, probably)

Code partially works. asserts fail, but I can't see why.

I'm obviously missing something here.

To me, it may be line 10 (I don't remember anything about 'assert' or 'metatable's anymore, so sorry if this doesn't help :( ), because it appears your comparing 'board[0]' to itself, although, I'm not too sure if this is the problem. TheeDeathCaster 2368 — 7y
`assert` checks if you gave it `true`. You can use it to make sure you're staying sane. In this case, it errors, because `board[0]` in fact is NOT `board[0]`, which is the problem I'm running into BlueTaslem 18071 — 7y
@Alpha; it means the metamethod is firing twice in that statement, when it shouldn't be firing at all due to line 8. adark 5487 — 7y

Locked by User#5978, Marios2, and BlueTaslem

This question has been locked to preserve its current state and prevent spam and unwanted comments and answers.

Why was this question closed?

1 answer

Log in to vote
Answered by
adark 5487 Badge of Merit Moderation Voter Community Moderator
7 years ago

The problem is super simple: you forgot the first parameter of __index, the Table being indexed!

Changing line 2 to:

setmetatable(board, {__index = function(_, row)

Fixed the problem for me.

EDIT: For anybody that doesn't understand metamethods, the reason the code didn't actually error is that you can use a Table as an index in Table. Any Table, including itself!

Basically, whenever __index was invoked, it was setting:

board[board] = t

Instead of the passed-in row.