This is a read-only snapshot of the ComputerCraft forums, taken in April 2020.
KaoS's profile picture

Variables clearing when new iteration of shell is called [FIXED]

Started by KaoS, 14 November 2012 - 02:12 AM
KaoS #1
Posted 14 November 2012 - 03:12 AM
Hi pro people, I am working on a rednet project that will make all rednet enabled computers automatically forward messages to ensure that they reach their destination. it must be saved in the startup file and when it re-launches the shell it launches the startup file again. this is 100% fine because when it launches the first time it sets the variable bGo to true and the second time it should detect that bGo is defined and not run shell again but for some reason the variable is erased. here is a pastebin of the full code so far

does anyone know why bGo loses its value?
Doyle3694 #2
Posted 14 November 2012 - 03:15 AM
Variables lose their values when your computer is reloaded, if that's waht you mean
KaoS #3
Posted 14 November 2012 - 03:24 AM
I'm not restarting it. I am just calling shell again. take a quick look at the code… I have now added a few basic comments to explain it
Lyqyd #4
Posted 14 November 2012 - 03:48 AM
That's because it's running in a new environment. Try using os.run(getfenv(), "/rom/programs/shell") instead.
KaoS #5
Posted 14 November 2012 - 03:49 AM
ahhhh. thanks man
KaoS #6
Posted 14 November 2012 - 04:02 AM
AAAAND it doesn't work :P/>/>

getfenv() has all global values in it but for some reason those aren't passed on to the new shell. don't know why

even if you use

  bGo=true
  local oldshell=shell
  shell=nil
  local tThreads={coroutine.wrap(co),coroutine.wrap(function() oldshell.run('rom/programs/shell') end)}
  local evts={}
  while true do
   for iNum,fThread in pairs(tThreads) do
    fThread(unpack(evts))
   end
   evts={os.pullEventRaw()}
  end
it doesn't work
ardera #7
Posted 14 November 2012 - 04:37 AM
Ok. If all local variables don't get listed from getfenv, you could try making your own filerun function.Code

function runFile(file)
  r=fs.open(file, "r")
  code=r.readAll()
  r.close()
  f=loadstring(code)
  f()

PS.: After thinking about the functionality of this function Im not really sure if it would work…
Orwell #8
Posted 14 November 2012 - 04:38 AM
I think the major problem is that the environment is explicitly set in the 'shell' program:

local tEnv = {
  ["shell"] = shell,
}
After that every program from shell is started through the 'run' function of 'shell', which does the call to 'os.run' in the following way:

local result = os.run( tEnv, sPath, ... )

So the environment you passed to shell will never be used except by the shell program itself ( it does pass the 'shell' table to another shell).

EDIT:
Since you want to use this shell after startup, you could use a custom shell. I guess you can just change this:

local tEnv = {
  ["shell"] = shell,
}
to:

local tEnv = getfenv()
tEnv['shell'] = shell
KaoS #9
Posted 14 November 2012 - 04:39 AM
I think rather than bother I will just create a file called bGo and use that instead. it just bugs me that you cannot keep the global variables
KaoS #10
Posted 14 November 2012 - 04:53 AM
Well I got it working now. also had to break the for loop that removed expired timers from the banned table or the for loop crashed. I would like to thank you guys for the help though. Orwell your answer was particularly enlightening. thanks

EDIT: oh yeah, almost forgot. the completed program is in the pastebin link in OP. if you would like to use it feel free. it may be updated from time to time