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

attempt to yield across metamethod/C-call boundary workaround?

Hello helpers! I am working on a Object Oriented Trello API at the moment. However, I stumbled upon a huge obstacle, which might make it impossible, however, I am not sure.

Basically, I have a metatable with the .__index metamethod in it. It allows me to "read" properties from Trello objects. Such as Board.Name, etc. However, there is an error.

attempt to yield across metamethod/C-call boundary

It happens when I try to HTTP GET from the metamethod, is there a way to work around this limitation?

Edit: Apparently I need to include the code, even though I stated exactly what I was doing, so here it is:

This is a modulescript, which in this case is the Board constructor:

local HTTP = game:GetService("HttpService")
local keys = require(script.Parent.Parent.keys)

local Board = {}

function Board:GetObject(id)
	local NewBoard = {}
	local Meta = {}
	Meta.__index = function(_, index)
		local Properties = {}

		Properties["Id"] = function()
			return id
		end
		
		Properties["Name"] = function()
			
			local Ret = HTTP:GetAsync("https://api.trello.com/1/boards/"..id..keys)
			return (HTTP:JSONDecode(Ret).name)
		end
		
		if Properties[index] then
			return Properties[index]()
		else
			error(index.." is not a valid member of Board.")
		end
	end
	setmetatable(NewBoard,Meta)
	
	return NewBoard
end

return Board

Also, I am aware I should pcall() my HTTP functions, but this is a test code, it is intended for testing only, and won't be the final product.

2 comments

1

I disagree with the comment, the issue is clearly stated, script will error when using httpservice inside the _index metamethod, and they're looking for ideas on how to bypass that.

1

I agree with you, but I'll just add the code anyway to avoid issues.

1 answer

Object orienting lua's a hard process, so best of luck to you. I got tired when I tried to introduce inheritance.

Anyway, the problem is you're calling something that yields like wait() does in __index, http get is not an instantaneous call.

You can try 'spawn'ing a bit of code inside __index that'll update a value once it's finished loading. It might be better though to move the actual code into a 'refresh' function that does the http get, and have the constructor perform a refresh initially if it makes sense to.

4 comments

0

Downvote without a comment why, sure.

0

I didn't downvote, but here is a note: It's not necessarily "something that uses wait." Things other than wait() can yield a script. The proper terminology would be: "something that yields in __index."

0

I meant it in that http get uses wait, but I'll edit for clarity

0

After a lot of research, it appears that I cannot use metamethods to read data, there's just no way. It would only work in Lua 5.3 or LuaJIT

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