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

Help with recursion.

Started by Molinko, 18 March 2013 - 08:05 PM
Molinko #1
Posted 18 March 2013 - 09:05 PM
I'm in need of some help with a recursive function.. I would like it to be able to print out an entire table and all included tables, however when i use this on very long tables it will hang eventually at the end of one of the sub tables. If you could help me figure out how to achieve this i would greatly appreciate it.

-- table expander --
os.loadAPI("ocs/apis/sensor")
term.clear()
term.setCursorPos(1,1)

local function expand(tab) --"tab" is a table derp
  for k,v in pairs(tab) do
    print(tostring(k)..": ")
    if type(v) ~= "table" then
	  print(tostring(v))
    else
	  return pcall(expand(v))--gets stuck at the end of one table...
    end
  end
end

local prox = sensor.wrap("top")
local targets = prox.getTargets()
local tDetails = prox.getTargetDetails("Molinko")
--expand(targets) --success?!
expand(tDetails)
Thanks for any help :ph34r:/>
Lyqyd #2
Posted 19 March 2013 - 03:43 AM
Split into new topic.
theoriginalbit #3
Posted 19 March 2013 - 03:53 AM
This is how pcall works…

pcall(function_pointer, param1, param2, param3, ...)

But I don't see why you have to do that at all and the return. something like this should work fine.

local function expand(tab) --"tab" is a table derp
  for k,v in pairs(tab) do
	print(tostring(k)..": ")
	if type(v) ~= "table" then
	  print(tostring(v))
	else
	  expand(v)
	end
  end
end

You may want to add a sleep(0) at the end of each loop, just incase its going to take >10 seconds to iterate.
Molinko #4
Posted 19 March 2013 - 06:06 AM
This is how pcall works…

pcall(function_pointer, param1, param2, param3, ...)

But I don't see why you have to do that at all and the return. something like this should work fine.

local function expand(tab) --"tab" is a table derp
  for k,v in pairs(tab) do
	print(tostring(k)..": ")
	if type(v) ~= "table" then
	  print(tostring(v))
	else
	  expand(v)
	end
  end
end

You may want to add a sleep(0) at the end of each loop, just incase its going to take >10 seconds to iterate.

I was just using pcall to see when in the loop i was having an issue… But ive never used it before. I shouldve cleaned that out before posting… I added a sleep(0) in there too after my if statment and i works like a charm.. Thanks for the tip TheOriginalBit,
not sure why i didnt think of that :3
Molinko #5
Posted 19 March 2013 - 07:57 AM
Sorry to add a little off topic but whn i try and wtire this data to a monitor i have to use write(v) bu tI would like it to start a newline..
when i try to use a line escape it doesnt work… ive tried m.write(tostring(v).."\n") but it write a "?" to the screen instead of a line escape. thanks for your help and let me know if you need the code for this help. thank you
MysticT #6
Posted 19 March 2013 - 08:01 AM
The easiest way to do that is to use term.redirect:

local mon = peripheral.wrap("left") -- or whatever you use to wrap the monitor
term.redirect(mon) -- redirect output to the monitor
-- print whatever you want here, using write or print
print("Hello World!") -- example. This will be printed in the monitor
term.restore() -- restore output to the terminal
Molinko #7
Posted 19 March 2013 - 08:15 AM
The easiest way to do that is to use term.redirect:

local mon = peripheral.wrap("left") -- or whatever you use to wrap the monitor
term.redirect(mon) -- redirect output to the monitor
-- print whatever you want here, using write or print
print("Hello World!") -- example. This will be printed in the monitor
term.restore() -- restore output to the terminal

yeah i just figured this out thanks MysticT.. btw i had to use term.redirect(term.native) to restore control back to the terminal. just a heads up there. But for future reference is it possible to do the first way i was trying? or is it just not really practical??
MysticT #8
Posted 19 March 2013 - 09:16 AM
btw i had to use term.redirect(term.native) to restore control back to the terminal.
You should use term.restore, that's what it is for. Redirecting to the native term will fill the redirect stack each time you run the program.

But for future reference is it possible to do the first way i was trying? or is it just not really practical??
Yes it is, just a little harder. You have to move the cursor yourself using mon.setCursorPos, and there's no support for line break or word wraping.
Molinko #9
Posted 19 March 2013 - 10:27 AM
btw i had to use term.redirect(term.native) to restore control back to the terminal.
You should use term.restore, that's what it is for. Redirecting to the native term will fill the redirect stack each time you run the program.

But for future reference is it possible to do the first way i was trying? or is it just not really practical??
Yes it is, just a little harder. You have to move the cursor yourself using mon.setCursorPos, and there's no support for line break or word wraping.
Thats what i was worried about. Figured having a line break or setting the ystart for writing would be too hard if not even possible within a recursive for loop… crap. but thank you for your help. Much appreciated