Scripting HelpersARCHIVE
A little piece of Roblox history. Preserved for everyone, one question at a time.Read about the archive →
✓ ANSWER ACCEPTED

Why is this __index metatable not saving the row correctly?

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;
end});

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.

3 comments

0

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.

0

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

0

@Alpha; it means the metamethod is firing twice in that statement, when it shouldn't be firing at all due to line 8.

1 answer

✓ Accepted answer

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.

This discussion is preserved as it was. New answers, comments, and votes are closed.