Quick Question About Metatable!

Guys, I got a small quick question,
So I’m still learning about metatables, so I’m kinda confused what does this piece of code do.
image

As we all know, the output will print the table itself, the index of the table and the nil, right ?
But I’m confused at this point : how did the function know the variable ‘x’ is the index of the ‘tab’ table eventhough we don’t tell it which one is? I think it’s because the index function is automatically define the first 2 variables as the table and the index but I’m not sure about it, that’s why I’m posting question here.
And, if it’s true, can we change the order of the variables?
It’ll be nice if you guys can share a bit of time answering my question, thank you!

__index expects you to return something.

Instead of printing within the index metamethod, you return it instead:

__index = function(tab, x)
    return tab[x]
end

I’m not sure what you’re trying to ask so this was my best guess.

1 Like

No, metamethods are managed internally

1 Like

The output will be:

{} k
nil

When you index the table, it will print the table and the key you indexed. But since you printed the result, it will also print nil. __index will return a value, but in the code, it returns nothing.

1 Like

Thank you all for spending time answering my question, but none of them is the answer I’m looking for.
This image might make my question more clearly

So it’s supposed to print the table and the key if I index them right ?
Then without printing the result, it should still work as said.
But I tested it out by delete the print(newtab["k"]) line and replace it with
newtab["k"] = 1 -- random number . The print still won’t show up

__index is a metamethod and it fires when a table is indexed with a key, to which nothing is stored, so it would normally be nil. The point of metatables is to expand the functionality of tables. __index helps us respond or point with our own code.

The process is handled internally and exists in vanilla lua. If __index is pointed to a function, it’s going to automatically send you the table metatable is attached to, and the indexed key.

local cars = {}
setmetatable(cars, {
	__index = function(tabl, key)
		return "We don't have that car."
	end,
})

cars["Ford"] = true

print(cars["Ford"]) --> true
print(cars["Audi"]) --> We don't have that car.

-- after buying Audi
cars["Audi"] = true
print(cars["Audi"]) --> true

We can also point to another table. For example:

local cars = {}
local sportsCars = {
	["Porsche"] = true;
}

setmetatable(cars, {
	__index = sportsCars
})

print(cars.Porsche) --> true

Should a car not exist in cars, __index will point to sportsCars and look there before returning nil.

This is particularly useful in object oriented programming (OOP). We essentially return a customized table object and set a metatable linking it back to the class. So if someone tries to call a function on our returned object and it’s not found there, index will search for it in the class.

__newindex is similar, but fires when it detects an attempt to add a new value to key that previously held a nil value. In the function it will automatically pass table, key and value. At that point we can decide whether to allow the change in the table or not. If we don’t, we can simply return anything, but if we do, we have to do some raw writing - writing to the table without waking metatables.

__index = function(self, key, value)
	rawset(self, key, value)
	return;
end,
1 Like

This is the answer I was looking for, thank you so much!

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.