Scripting Helpers is winding down operations and is now read-only. More info→
Ad
Log in to vote
1

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

Asked by 5 years ago
Edited 5 years ago

Please include the code which you are trying to use, so the community will be better-equipped to help you with your problem.

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.

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. clc02 553 — 5y
1
I agree with you, but I'll just add the code anyway to avoid issues. LisaF854 93 — 5y

1 answer

Log in to vote
-1
Answered by
clc02 553 Moderation Voter
5 years ago
Edited 5 years ago

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.

0
Downvote without a comment why, sure. clc02 553 — 5y
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." User#25115 0 — 5y
0
I meant it in that http get uses wait, but I'll edit for clarity clc02 553 — 5y
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 LisaF854 93 — 5y
Ad

Answer this question