Faulty code in Using Metatables section

The code for the example of calling a table as an function does not return the expected result. Running this code causes a stack overflow.

Code:

Result of running this code:
result

This is caused because of line 4 (“for i, value in t do”) . “t” gets called because of this and that creates infinite recursion.

Page URL: https://create.roblox.com/docs/luau/metatables#using-metatables

1 Like

(Just putting this here)


The code sample should look like this:

local metatable = {
    __call = function(t, param)
    	local sum = {}
    	for i, value in ipairs(t) do
    		sum[i] = value + param -- Add the argument (5) to the value, then place it in the new table (t).
    	end
    	return unpack(sum) -- Return the individual table values
    end
}

local t = setmetatable({10, 20, 30}, metatable)
print(t(5)) --> 15 25 35

This is one of those cases where ipairs/pairs/next is needed because the __call metamethod is invoked for any table that’s used for generalized iteration

2 Likes

Another way would be defining a __iter method for example:

local metatable = {
	__call = function(t, param)
		local sum = {}
		for i, value in t do
			sum[i] = value + param -- Add the argument (5) to the value, then place it in the new table (t).
		end
		return unpack(sum) -- Return the individual table values
	end,
	
	__iter = ipairs -- Could be a custom iterator function aswell
}

local t = setmetatable({10, 20, 30}, metatable)
print(t(5)) --> 15 25 35
1 Like

Declaring the __iter metamethod and/or using pairs/ipairs is a valid way to bypass this error. However if you don’t want to modify the behavior of generalized iteration (ipairs iterates indexes until nil, pairs iterates indexes and then keys), rawget() is the right way to do this:

local t = setmetatable({}, {
     __index = function(t, k)
          return rawget(t, k)
     end,
})
1 Like

Hi! I have merged a change to the documentation replacing t with ipairs(t). Thank you for bringing this to our attention!

2 Likes

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