This is a read-only snapshot of the ComputerCraft forums,
taken in April 2020.
Parallel variable issues
Started by ShadowDisruptor, 30 November 2014 - 06:01 PMPosted 30 November 2014 - 07:01 PM
Hello! I'm running a script that uses a parallel to run 2 functions. The functions work fine without being called in parallel, but when in parallel, they cannot access variables outside from that function. Any help?
Posted 30 November 2014 - 07:06 PM
Post the code so we can see what you're doing to the variables in question.
Posted 30 November 2014 - 07:07 PM
I don't believe parallel messes around with function environments, so I don't really see what's going on here. Seeing some code would be very useful.
Are you sure you're passing the functions into parallel, and not calling them? Sometimes people do this:
Are you sure you're passing the functions into parallel, and not calling them? Sometimes people do this:
parallel.waitForAny( foo(), bar() )
when instead it should be this:
parallel.waitForAny( foo, bar )
Edited on 30 November 2014 - 06:08 PM
Posted 30 November 2014 - 07:10 PM
Post the code so we can see what you're doing to the variables in question.
Sending them via rednet.
if message == "does_exist" then
serverHad = true
rednet.send(servers[i], "LOL", "delete_"..variable)--'variable' is the variable outside the function. Note, this is a snip of the 100 line function.
value = "deleted."
writeValue()
end
I don't believe parallel messes around with function environments, so I don't really see what's going on here. Seeing some code would be very useful.
Are you sure you're passing the functions into parallel, and not calling them? Sometimes people do this:when instead it should be this:parallel.waitForAny( foo(), bar() )
parallel.waitForAny( foo, bar )
while true do
parallel.waitForAny(clickDetect, rednetDetect)
end
Positive.Posted 30 November 2014 - 07:30 PM
Is 'variable' global or local? Is that erring "attempt to concatenate string and nil" or is it just not being updated? Posting the whole code would help, or at least a bit more than that.
Posted 30 November 2014 - 07:32 PM
You should use a while true loop with parallel as it creates some issues
Posted 30 November 2014 - 07:37 PM
It is "attempt to concatenate string and nil" The variable isn't local, nor is it global. (Example: variable = "click to edit.")Is 'variable' global or local? Is that erring "attempt to concatenate string and nil" or is it just not being updated? Posting the whole code would help, or at least a bit more than that.
I am using a while loop, do you mean shouldn't use?You should use a while true loop with parallel as it creates some issues
For those asking for source, have fun.
http://pastebin.com/0wdZbZN9
Posted 30 November 2014 - 07:49 PM
'variable = "blah" ' means it is global, just so you know.
I might be wrong about parallel messing with function environments, so just to be safe I'd put 'variable' and 'value' at the top as local variables. That way, no matter how hard parallel tries, it can't make either of them nil.
It is a pretty weird error though, I can't see anywhere where 'variable' could be made equal to nil.
Just for future reference, using global variables is pretty much always a bad idea. They are slower, can be changed by other programs, and use up memory even after the code they are used in stops.
I might be wrong about parallel messing with function environments, so just to be safe I'd put 'variable' and 'value' at the top as local variables. That way, no matter how hard parallel tries, it can't make either of them nil.
It is a pretty weird error though, I can't see anywhere where 'variable' could be made equal to nil.
Just for future reference, using global variables is pretty much always a bad idea. They are slower, can be changed by other programs, and use up memory even after the code they are used in stops.
Posted 30 November 2014 - 07:55 PM
It is "attempt to concatenate string and nil" The variable isn't local, nor is it global. (Example: variable = "click to edit.")Is 'variable' global or local? Is that erring "attempt to concatenate string and nil" or is it just not being updated? Posting the whole code would help, or at least a bit more than that.I am using a while loop, do you mean shouldn't use?You should use a while true loop with parallel as it creates some issues
For those asking for source, have fun.
http://pastebin.com/0wdZbZN9
Using parallel within a while loop works fine (as well as using it outside of a while loop), I'm not sure where TurtleHunter got the idea that it there are 'issues' with one way or the other.
As for local/global variables - your example (variable = "click to edit") defines a global variable - basically if it's not localized then it's global. Keep in mind that some variables are 'automatically' localized - (e.g. loops - for example a generic loop like 'for k, v in pairs' … the k and v are automatically localized), but when you declare a variable like you did, it needs to be explicitly localized or it is a global.
:ph34r:/> 'd
Edited on 30 November 2014 - 06:57 PM
Posted 30 November 2014 - 07:56 PM
'variable = "blah" ' means it is global, just so you know.
I might be wrong about parallel messing with function environments, so just to be safe I'd put 'variable' and 'value' at the top as local variables. That way, no matter how hard parallel tries, it can't make either of them nil.
It is a pretty weird error though, I can't see anywhere where 'variable' could be made equal to nil.
Just for future reference, using global variables is pretty much always a bad idea. They are slower, can be changed by other programs, and use up memory even after the code they are used in stops.
Adding the local at the top of function dosent work. Any other suggestions?
Posted 30 November 2014 - 07:58 PM
Not at the top of the function, at the top of the whole code.
Like this…
Like this…
local variable = "blah"
function setVariable()
end
...
Posted 30 November 2014 - 07:58 PM
Changing to local at the top keeps the same errors.It is "attempt to concatenate string and nil" The variable isn't local, nor is it global. (Example: variable = "click to edit.")Is 'variable' global or local? Is that erring "attempt to concatenate string and nil" or is it just not being updated? Posting the whole code would help, or at least a bit more than that.I am using a while loop, do you mean shouldn't use?You should use a while true loop with parallel as it creates some issues
For those asking for source, have fun.
http://pastebin.com/0wdZbZN9
Using parallel within a while loop works fine (as well as using it outside of a while loop), I'm not sure where TurtleHunter got the idea that it there are 'issues' with one way or the other.
As for local/global variables - your example (variable = "click to edit") defines a global variable - basically if it's not localized then it's global. Keep in mind that some variables are 'automatically' localized - (e.g. loops - for example a generic loop like 'for k, v in pairs' … the k and v are automatically localized), but when you declare a variable like you did, it needs to be explicitly localized or it is a global.
Same error.Not at the top of the function, at the top of the whole code.
Like this…local variable = "blah" function setVariable() end ...
EDIT: Also getting another error, "window:155: bad argument: string expected, got nil" on initial startup of the script
Edited on 30 November 2014 - 07:01 PM
Posted 30 November 2014 - 08:00 PM
After looking at the code I saw that you are giving 'variable' a value and the only function that could somehow set 'variable' to nil is 'read()' which never returns nil. Just to be sure, have you tried to reboot the computer and run this, and only this, program?
EDIT: try this:
EDIT: try this:
resetGraphics()
while true do
print( type(variable) ) <-- #right here
parallel.waitForAny(clickDetect, rednetDetect)
end
Edited on 30 November 2014 - 07:04 PM
Posted 30 November 2014 - 08:03 PM
I'm running this in CCEmuRedux, could this be the issue? If someone could try running this script in a real game, it would help to know if that's the error.
This is the only program I'm running. Rebooted multiple times.
After looking at the code I saw that you are giving 'variable' a value and the only function that could somehow set 'variable' to nil is 'read()' which never returns nil. Just to be sure, have you tried to reboot the computer and run this, and only this, program?
This is the only program I'm running. Rebooted multiple times.
Posted 30 November 2014 - 08:07 PM
I'm running this in CCEmuRedux, …
Yeah.. you could have said that earlier. If something doesn't work in an emulator, try it in-game. Emulators are not 100% perfect, especially if you are using Rednet with them.
Posted 30 November 2014 - 08:09 PM
Just thought about saying it, my bad. I don't currently have a modpack set up with the correct version of CC. I guess I will work on making a pack to test it. Thanks for the help :)/>I'm running this in CCEmuRedux, …
Yeah.. you could have said that earlier. If something doesn't work in an emulator, try it in-game. Emulators are not 100% perfect, especially if you are using Rednet with them.
Posted 30 November 2014 - 08:18 PM
Turns out nothing happens at all ingame.. the clicks work, but none of the rednet transactions occur. When I press a button, everything freezes up.snip
Edited on 30 November 2014 - 07:19 PM
Posted 30 November 2014 - 08:19 PM
Check your IDs. Also, you define the 'servers' variable two times in the code.
Posted 30 November 2014 - 08:21 PM
Where's the second call? That's probably the issue, I did have the correct ID's.Check your IDs. Also, you define the 'servers' variable two times in the code.
EDIT: Found it! Sadly we're back where we started, same issue.
Edited on 30 November 2014 - 07:26 PM
Posted 30 November 2014 - 08:29 PM
I think something external must be setting variable to nil, as read() NEVER returns nil. Are there any other programs or coroutines running?
The only other thing I can think of is this:
The only other thing I can think of is this:
local function test()
return 2 + nil
end
test() -- the error pops up here, not line 2
And rednet.send is returning an error, like above.Edited on 30 November 2014 - 07:29 PM
Posted 30 November 2014 - 08:40 PM
I think something external must be setting variable to nil, as read() NEVER returns nil. Are there any other programs or coroutines running?
The only other thing I can think of is this:And rednet.send is returning an error, like above.local function test() return 2 + nil end test() -- the error pops up here, not line 2
I'm not 100% sure it's the rednet. It's something we're doing inside clickDetect() the rednetDetect() function works flawlessly. There's nothing else running on that computer.
EDIT: Variable and value could be set to nil if it's not getting the data from the rednet, but my code is made to prevent that. (Communicates with the database to make sure something exists before asking for it)
Edited on 30 November 2014 - 07:41 PM
Posted 30 November 2014 - 11:14 PM
Got some data that might help break it down.
1) It's in this section of code
2) The 'does exist' check always runs
3) If both servers have the variable, it also does the action and crashes after. Otherwise, only the exist check works
1) It's in this section of code
if(y == 8) then
if((x >= 3) and (x <= 7)) then
serverHad = false
for i=1, #servers do
rednet.send(servers[i], "LOL", "has_"..variable)
while true do
id,message = rednet.receive()
if id == servers[i] then
if message == "does_exist" then
serverHad = true
rednet.send(servers[i], "LOL", "get_"..variable)
while true do
id,message = rednet.receive()
if id == servers[i] then
value = message
writeValue()
break
end
end
end
break
end
end
end
if not(serverHad) then
value = "Dosen't exist :(/>"
writeValue()
end
end
if((x >= 9) and (x <= 13)) then
serverHad = false
for i=1, #servers do
rednet.send(servers[i], "LOL", "has_"..variable)
while true do
id,message = rednet.receive()
if id == servers[i] then
if message == "does_exist" then
serverHad = true
rednet.send(servers[i], value, "set_"..variable)
end
break
end
end
end
if not(serverHad) then
local randomNum = math.random(#servers)
rednet.send(servers[randomNum], value, "set_"..variable)
end
end
if((x >= 15) and (x <= 22)) then
serverHad = false
for i=1, #servers do
rednet.send(servers[i], "LOL", "has_"..variable)
while true do
id,message = rednet.receive()
if id == servers[i] then
if message == "does_exist" then
serverHad = true
rednet.send(servers[i], "LOL", "delete_"..variable)
value = "deleted."
writeValue()
end
break
end
end
end
if not(serverHad) then
value = "Dosen't exist :(/>"
writeValue()
end
end
if((x >= 24) and (x <= 37)) then
shell.run("edit servers")
resetGraphics()
end
end
2) The 'does exist' check always runs
--This is what that looks like
rednet.send(servers[i], "DERP", "has_"..tempVar)
while true do
id2,message2 = rednet.receive()
if id2 == servers[i] then
if message == "does_exist" then
goodMatch = true
rednet.send(servers[i], message, "set_"..tempVar)
end
break
end
end
3) If both servers have the variable, it also does the action and crashes after. Otherwise, only the exist check works
Posted 01 December 2014 - 06:16 PM
'variable = "blah" ' means it is global, just so you know.
I might be wrong about parallel messing with function environments, so just to be safe I'd put 'variable' and 'value' at the top as local variables. That way, no matter how hard parallel tries, it can't make either of them nil.
It is a pretty weird error though, I can't see anywhere where 'variable' could be made equal to nil.
Just for future reference, using global variables is pretty much always a bad idea. They are slower, can be changed by other programs, and use up memory even after the code they are used in stops.
Not true, _G['variable'] and variable are very different things. variable is global to it's scope, while _G['variable'] is global to all scopes.
Posted 01 December 2014 - 06:32 PM
Not always, that's just how CraftOS does it. You can give a _G when you set a function environment (and if you don't it isn't given automatically), and setting a variable in the current scope is almost always referred to as setting a global.'variable = "blah" ' means it is global, just so you know.
I might be wrong about parallel messing with function environments, so just to be safe I'd put 'variable' and 'value' at the top as local variables. That way, no matter how hard parallel tries, it can't make either of them nil.
It is a pretty weird error though, I can't see anywhere where 'variable' could be made equal to nil.
Just for future reference, using global variables is pretty much always a bad idea. They are slower, can be changed by other programs, and use up memory even after the code they are used in stops.
Not true, _G['variable'] and variable are very different things. variable is global to it's scope, while _G['variable'] is global to all scopes.
Edit: also, a (function) scope includes local variables to that function.
Edited on 01 December 2014 - 05:39 PM