1

So, I'm trying to get a variable out of a function. I have a Garry's Mod script which contains this statement:

http.Fetch("http://google.fr",  function(body)
    return body
end)

My question is: how to retrieve my body variable out of this? I think that there's no such thing as "global" keyword (like in PHP for example) or references in Lua. Thanks!

GilDev
  • 514
  • 5
  • 14
  • If you have a function that returns a variable, then `local result = foo()`... – The Paramagnetic Croissant Aug 13 '14 at 20:07
  • The callback you pass won't be called until after the page is fetched, which will be well after the function calling `http.Fetch` returns. – Colonel Thirty Two Aug 13 '14 at 20:13
  • @TheParamagneticCroissant I don't fully understand and I can't get it to work this way. – GilDev Aug 13 '14 at 21:17
  • @ColonelThirtyTwo You're right, so my code **should** be inbetween the callback function so I can't use the body value if the page hasn't loaded. But is there still a way to retrieve the variable out of this? – GilDev Aug 13 '14 at 21:18

3 Answers3

0

If you can't simply return the value from a function, you can us an upvalue to update, which will be available after the function is executed:

local bodycopy
http.Fetch("http://google.fr",  function(body)
    bodycopy = body
end)
-- assuming http.Fetch block here until the content of the URL is retrieved...
print(bodycopy)
Paul Kulchenko
  • 25,884
  • 3
  • 38
  • 56
0

I think that there's no such thing as "global" keyword (like in PHP for example) or references in Lua.

There's closures, which will let you access variables defined as local in a subfunction.

For example:

function makeCounter()
    local i = 0
    local function counterfunc()
        i = i + 1
        return i
    end
    return coutnerfunc
end

local counter1 = makeCounter()
print(counter1()) -- 1
print(counter1()) -- 2
print(counter1()) -- 3

local counter2 = makeCounter()
print(counter2()) -- 1
print(counter2()) -- 2

print(counter1()) -- 4

This means you can store objects for use in your callback function.

function ENT:GetPage()
    -- The implicitly-defined self variable...
    http.Fetch("www.example.com", function(body)
        -- ...is still available here.
        self.results = body
    end)
end

Note that http.Fetch is an asynchronous function; it calls the callback later when the page is actually fetched. This won't work:

function ENT:GetPage()
    local results
    http.Fetch("www.example.com", function(body)
        results = body
    end)
    return results -- The closure hasn't been called yet, so this is still nil.
end
Colonel Thirty Two
  • 23,953
  • 8
  • 45
  • 85
0

the easiest way for you to handle this would be to write a function that physically loads the body result to whatever interface you are using, or to add code inside the Fetch call to load it yourself. Something like this:

-- just an example of some function that knew how to load a body result 
-- in your context
function setBody(body) 
    someapi.Display(body)
end

http.Fetch('http://someurl.com', 
    function(body) 
        -- you have access to outer functions from this scope. if you have
        -- some function or method for loading the response, invoke it here
        setBody(body)
        -- or just someapi.Display(body)
    end
)

I think you are confused because you seem to be in more of a functional design mindset, and you're now mixing in event driven design. in the event driven design, you are basically calling functions with params and giving them a function callback that has some code that you want to eventually run once the function you invoked completes.

Also, there is a global keyword of sorts in Lua - you have the global table _G. You could potentially set _G.body = body, but I would avoid that and pass around callback functions that know how to load things once they are invoked.

Mike Corcoran
  • 14,072
  • 4
  • 37
  • 49