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

[Lua][Error]:50: Expected string got nil

Started by dimitriye98, 09 September 2012 - 03:22 AM
dimitriye98 #1
Posted 09 September 2012 - 05:22 AM

local maxX, maxY = term.getSize()
maxX = maxX-2
function elementOf(table, object)
for index,value in pairs(table) do
  if object == value then
   return true
  end
end
return false
end
local wordSeparators = {" ", "/", "\\", "-"}
function drawPage(sPage)
local lines = {}
local function iterChars(string)
  return function(s, c)
   c = c+1
   local char = string.sub(string, c, c)
   if #char == 0 then
	char = nil
	return nil
   else
	char = nil
	return c, string.sub(c, c)
   end
  end, string, 0
end
local bufferLine = ""
local bufferWord = ""
for pos, char in iterChars(sPage) do
  local len = string.len(bufferLine)+string.len(bufferWord)+1
  if len >= maxX then
   table.insert(lines, bufferLine)
   bufferLine = ""
  end
  if elementOf(wordSeparators, char) then
   bufferLine = bufferLine..bufferWord..char
  elseif char == "\n" then
   bufferLine = bufferLine..bufferWord
   table.insert(lines, bufferLine)
   bufferLine = ""
  else
   bufferWord = bufferWord..char
  end
end
local function redraw(startLine)
  local drawtext = table.concat(lines, "\n", startLine, startLine+maxY-1)
  term.clear()
  term.setCursorPos(1, 1)
  write(drawtext)
end
local cursorPos = 1
redraw(cursorPos)
while true do
  local event, key = os.pullEvent("key")
  if key == keys.up and cursorPos > 1 then
   cursorPos = cursorPos-1
   redraw(cursorPos)
  elseif key == keys.down and cursorPos < (#lines-maxY+1) then
   cursorPos = cursorPos+1
   redraw(cursorPos)
  end
end
end

drawPage([[<snip long lorem ipsum>]])

I have no idea why this is broken… As far as I know the only string that table.concat accepts is the separator and I explicitly declared that.
Kazimir #2
Posted 09 September 2012 - 05:32 AM
You have one function of within the other, as it should be?
dimitriye98 #3
Posted 09 September 2012 - 05:55 PM
Yeah, I want to create a local function within the other function's closure so that it won't be accessible outside the local function.

Edit: I meant to say so that it won't be accessible outside the closure.
ltstingray #4
Posted 09 September 2012 - 06:04 PM
in your function drawPage line (a variable you're calling in another function) is set to local. Either return it make it global or define it in the head.

Since redraw() can't access the variable it's reading it as nil
Lyqyd #5
Posted 09 September 2012 - 06:23 PM
in your function drawPage line (a variable you're calling in another function) is set to local. Either return it make it global or define it in the head.

Since redraw() can't access the variable it's reading it as nil

This is not correct. The lines table is declared in the function containing the redraw function, so it can access the variable, theoretically. It may be helpful to throw a print(type(lines)) statement above the table.concat() to confirm that this is actually happening, though.
ltstingray #6
Posted 09 September 2012 - 06:32 PM
in your function drawPage line (a variable you're calling in another function) is set to local. Either return it make it global or define it in the head.

Since redraw() can't access the variable it's reading it as nil

This is not correct. The lines table is declared in the function containing the redraw function, so it can access the variable, theoretically. It may be helpful to throw a print(type(lines)) statement above the table.concat() to confirm that this is actually happening, though.

um no…

the only place lines{} is declared in drawPage

ctrl+f lines

I just checked, double checked and triple checked.

Feel free to point out what I'm missing if I'm missing something.

function drawPage(sPage)
local lines = {}
local function iterChars(string)
  return function(s, c)
   c = c+1
   local char = string.sub(string, c, c)
   if #char == 0 then
	    char = nil
	    return nil
   else
	    char = nil
	    return c, string.sub(c, c)
   end
  end, string, 0
end

while redraw is trying to access it


local function redraw(startLine)
  local drawtext = table.concat(lines, "n", startLine, startLine+maxY-1)
  term.clear()
  term.setCursorPos(1, 1)
  write(drawtext)
end
Lyqyd #7
Posted 09 September 2012 - 06:40 PM
You don't even have most of the drawPage function there! Here it is, properly formatted. Now, where is the redraw function?


function drawPage(sPage)
    local lines = {}
    local function iterChars(string)
        return function(s, c)
            c = c+1
            local char = string.sub(string, c, c)
            if #char == 0 then
                char = nil
                return nil
            else
                char = nil
                return c, string.sub(c, c)
            end
        end, string, 0
    end    
    local bufferLine = ""
    local bufferWord = ""
    for pos, char in iterChars(sPage) do
        local len = string.len(bufferLine)+string.len(bufferWord)+1
        if len >= maxX then
            table.insert(lines, bufferLine)
            bufferLine = ""
        end
        if elementOf(wordSeparators, char) then
            bufferLine = bufferLine..bufferWord..char
        elseif char == "n" then
            bufferLine = bufferLine..bufferWord
        table.insert(lines, bufferLine)
            bufferLine = ""
        else
            bufferWord = bufferWord..char
        end
    end
    local function redraw(startLine)
        local drawtext = table.concat(lines, "n", startLine, startLine+maxY-1)
        term.clear()
        term.setCursorPos(1, 1)
        write(drawtext)
    end
    local cursorPos = 1
    redraw(cursorPos)
    while true do
        local event, key = os.pullEvent("key")
        if key == keys.up and cursorPos > 1 then
            cursorPos = cursorPos-1
            redraw(cursorPos)
        elseif key == keys.down and cursorPos < (#lines-maxY+1) then
            cursorPos = cursorPos+1
            redraw(cursorPos)
        end
    end
end
ltstingray #8
Posted 09 September 2012 - 06:46 PM
ahh, ok then, the formatting messed me up, I missed the second end ending the return and read it as ending iterChars.

proceed and thanks for pointing that out.
dimitriye98 #9
Posted 10 September 2012 - 12:26 AM
Ok, thank you for debating over weather I have a certain problem, now that you've concluded that it isn't that, can you please figure out what it is? :D/>/> Not trying to be rude or anything.

Edit: BTW line 50 is that call to concat.
Lyqyd #10
Posted 10 September 2012 - 01:14 AM
It may be helpful to throw a print(type(lines)) statement above the table.concat() to confirm that this is actually happening, though.

What was the result of this, then?
Magus #11
Posted 10 September 2012 - 11:53 AM
table.concat generates this error when the range contains indexes
not valid for the table, because tbl[key]=nil for keys not in the table