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

Global Variables with Dynamic Names Problems

Started by Snow van Night, 07 January 2015 - 06:34 PM
Snow van Night #1
Posted 07 January 2015 - 07:34 PM
Hey guys,
i have a problem with the program i try to write,
when i write

variable = mt[x][y]
it is working
but when i write

variable=_G["mt"..i][x][y]
it isn't working.

Could it be that _G isn't working in computer craft?
Lyqyd #2
Posted 07 January 2015 - 08:40 PM
You're probably going about this very much the hard way. I suspect that there's no need to use _G at all to accomplish whatever you're actually trying to do, and that there's a much easier way to do it. Please post the rest of the code.

Also, _G does work fine in CC, it just isn't where "global" variables from your running program end up (which is a good thing).
Snow van Night #3
Posted 07 January 2015 - 10:09 PM

while true do
  for i=1, 51 do
for j=1, 19 do
   local  os_cur =os_mt_screen[i][j]
   paintutils.drawPixel(i,j,_G["os_graphic".. 0][i-_G["x"..os_mt_screen[i][j]]][_G["y"..os_mt_screen[i][j]]])
   paintutils.drawPixel(i,j,os_graphic0[i][j] )
   if os_text0[i][j] ~= "" then
	 term.setCursorPos(i,j)
	 term.write(_G["os_text"..os_cur][i-_G["x"..os_cur]][j-_G["y"..os_cur]])
   end
end
  end
  sleep(10)
end
that is my code
all used variables are global and are set by other programs
this is one program of the operating system, i'm working on
Edited on 07 January 2015 - 10:28 PM
Bomb Bloke #4
Posted 08 January 2015 - 02:55 AM
Instead of having os_text0[j], os_text1[j], os_text2[j] etc, why not just have os_text[0][j], os_text[1][j], os_text[2][j] etc?
Snow van Night #5
Posted 08 January 2015 - 07:31 AM
cause every program create an own graphic and text file and the number is dependent on the task number that is used to create the window.
Furthermore every program has an own window size.
for restarts of the computer all variables are saved in files in a folder even the os_grafic and os_text files, it would be too complicated to save them when all programs write to one file.



this is the idea of os_mt_screen
Edited on 08 January 2015 - 07:12 AM
Bomb Bloke #6
Posted 08 January 2015 - 08:26 AM
… nope, I'm not getting it. I don't see how any of that relates to or would be disallowed by the table structure I suggested.

For eg, you might reformat the code snippet you posted earlier like so:

while true do
  for i=1, 51 do
for j=1, 19 do
   local  os_cur = os_mt_screen[i][j]
   paintutils.drawPixel(i,j,os_graphic[0][i-xTable[os_cur]][yTable[os_cur]])
   paintutils.drawPixel(i,j,os_graphic[0][i][j] )
   if os_text[0][i][j] ~= "" then
         term.setCursorPos(i,j)
         term.write(os_text[os_cur][i-xTable[os_cur]][j-yTable[os_cur]])
   end
end
  end
  sleep(10)
end

Odds are you'd be better off taking this further and cramming all your globals into subtables of one single table. That way you've really only got one global variable - and you want to keep those to a minimum.

It's probably worth pointing out that any user may hold Ctrl+R to force a reboot of a given system. There's no code you can run in "response" to this action.
Snow van Night #7
Posted 08 January 2015 - 09:30 AM
oh sorry i made a mistake in the post
this is the orginal code

while true do
  for i=1, 51 do
for j=1, 19 do
   local  os_cur =os_mt_screen[i][j]
   paintutils.drawPixel(i,j,_G["os_graphic".. os_cur][i-_G["x"..os_mt_screen[i][j]]][_G["y"..os_mt_screen[i][j]]])
   if os_text0[i][j] ~= "" then
	 term.setCursorPos(i,j)
	 term.write(_G["os_text"..os_cur][i-_G["x"..os_cur]][j-_G["y"..os_cur]])
   end
end
  end
  sleep(10)
end
this is happened because i test parts of the code.

basically the code do this:
1.check which window is active at pos i,j (os_mt_screen)
2.check which color the window have at this pos ("os_graphic".. os_cur)
3.draw pixel at pos i,j (paintutils.drawPixel)
2.check which text the window have at this pos ("os_text"..os_cur)
3.draw letter at pos i,j (term.write)

the idea is following:
if a new program is started it get a task number.
the task manager set up the os_mt_screen
the os_mt_screen comprise which pixel shows which window
every program with a graphical interface creates a os_graphic and a os_text file whitch contain all letters and pixels.
to differentiate the files they get the task number at the end of the file name
Edited on 08 January 2015 - 08:55 AM
Snow van Night #8
Posted 08 January 2015 - 10:03 AM
But basically i just wanna know: how did i get _G to work :blink:/>
Bomb Bloke #9
Posted 08 January 2015 - 12:13 PM
It's a matter of environments. Variables created by scripts in ComputerCraft typically go into a "user" environment (a separate table to _G), and globals in there can be accessed by any other scripts running on the same system. Those scripts can also access _G, as can APIs - though APIs can't access the "user" environment, and regular scripts can't access API environments. If you hunt down and read through bios.lua (in your ComputerCraft mod archive), you'll see how it's rigged up.

So, given that both your scripts and APIs can access _G, if you define your tables as specifically being in there then you'll be able to pull them out later. Eg:

_G["os_graphic0"] = {}  -- Force a new table into _G.
print(_G["os_graphic0"] == os_graphic0)  -- true

os_graphic0["hello"] = "moo"
print(os_graphic0["hello"] == _G["os_graphic0"]["hello"]) -- still true

os_graphic0 = {}  -- Now we have a new os_graphic0, in the user environment table (still making it global to all scripts in that environment)...
print(_G["os_graphic0"] == os_graphic0)  -- false!

os_graphic0 = nil  -- Clear the user environment version of "os_graphic0"
print(type(os_graphic0))  -- Guess!

oh sorry i made a mistake in the post
this is the orginal code

What I said still stands, and I'd see that code changed in much the same way as I posted earlier - you're better off making your own table for the purpose of storing all your other tables, rather than using _G. And that's even assuming you need to stick them somewhere your user's scripts can interfere with them at all!
Snow van Night #10
Posted 08 January 2015 - 03:11 PM
ohhhh! i don't want to create new variables.
isn't there a easy way to combine strings to an variable name?
it was never intended to use strange environments.
i just want combine strings to a variable name that is used then.
it seems so easy here: http://www.lua.org/pil/14.1.html

in the language GML i can just use asset_get_index()
Edited on 08 January 2015 - 02:23 PM
Lyqyd #11
Posted 08 January 2015 - 03:27 PM
Why? There's effectively no difference between tables named x1, x2, etc. and one table containing other tables at x[1], x[2], etc. The only exception is that the second way is much easier to deal with. There is no real reason to try to do this the first way. It's only more difficult to work with and offers literally no benefit over the second method.
Snow van Night #12
Posted 08 January 2015 - 04:21 PM
i'm working with combined variable names in a lot sections of the program!
some are more complex.
I just wanna know how i get combined variable names to work.
Lyqyd #13
Posted 08 January 2015 - 05:33 PM
Use the table getfenv() returns instead of _G.