Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    primarykey
    data
    text
    <p>You can define OutToUser in the scope of the handler:</p> <pre><code>function Server:init() local function handler(skt, host, port) --make the function local to here local function OutToUser(data) --references the skt variable in the enclosing scope --(the handler function) skt:send(data .. "\r\n") end while true do data = skt:receive() if data == "quit" then OutToUser(data) end end end local server = socket.bind("*", 49796) copas.addserver(server, function(c) return handler(copas.wrap(c), c:getpeername()) end ) copas.loop() end </code></pre> <p>Functions can always reference variables in their scope (function arguments and variables declared with <code>local</code>), even once they've left that scope - you can use that as an alternative solution, where you <em>enclose</em> the variables you want the function to use in a scope outside the function:</p> <pre><code>local function makeOTU(skt) --skt is visible in the scope of the function --that gets returned as a result return function(data) skt:send(data .. "\r\n") end end function Server:init() local function handler(skt, host, port) --create a function that references skt --as part of its closure local OutToUser = makeOTU(skt) while true do data = skt:receive() if data == "quit" then -- OutToUser is still referencing the -- skt from the call to makeOTU() OutToUser(data) end end end local server = socket.bind("*", 49796) copas.addserver(server, function(c) return handler(copas.wrap(c), c:getpeername()) end ) copas.loop() end </code></pre> <p>Note the use of the <code>local</code> keyword in both of these examples: if you neglect the <code>local</code>, the name will ignore the scope altogether and go into / come from <a href="http://www.lua.org/pil/14.html" rel="nofollow">the global environment</a> (which is just a table like any other: when you invoke a new Lua state, it's placed in the global <code>_G</code>), which is not what you want.</p> <p>Keeping your variables local to their scope instead of using globals is important. Take, for example, these two functions:</p> <pre><code>local function yakkity(file, message) line = message .. '\n' --without local, --equivalent to _G["line"] = message function yak() --without local, --equivalent to _G["yak"] = function() file:write(line) --since no local "line" is defined above, --equivalent to file:write(_G["line"]) end for i=1, 5 do yak() end end local function yakker(file, message) line = message .. '\n' --without local, --equivalent to _G["line"] = message return function() file:write(line) --again, since no local "line" is defined above, --equivalent to file:write(_G["line"]) end end </code></pre> <p>Because their variables aren't defined as local, they clobber each other's data, leave their belongings lying around where anybody can abuse them, and just generally act like slobs:</p> <pre><code>--open handles for two files we want: local yesfile = io.open ("yesyes.txt","w") local nofile = io.open ("no.txt","w") --get a function to print "yes!" - or, rather, --print the value of _G["line"], which we've defined to "yes!". --We'll see how long that lasts... local write_yes = yakker(yesfile,"yes!") --Calling write_yes() now will write "yes!" to our file. write_yes() --when we call yakkity, though, it redefines the global value of "line" --(_G["line"]) - as well as defining its yak() function globally! --So, while this function call does its job... yakkity(nofile, "oh no!") --calling write_yes(), which once again looks up the value of _G["line"], --now does the exact OPPOSITE of what it's supposed to- write_yes() --this writes "oh no!" to yesfile! --additionally, we can still write to the nofile handle we passed to yakkity() --by calling the globally-defined yak() function! yak() --this writes a sixth "oh no!" to nofile! --even once we're done with the file and close our handle to it... nofile:close() --yak() still refers to that handle and will still try to write to it! yak() --tries to write to the closed file handle and throws an error! </code></pre>
    singulars
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    1. VO
      singulars
      1. This table or related slice is empty.
    2. VO
      singulars
      1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload