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

Attempt to index ? (A nil value)

Started by thecrimulo, 26 July 2016 - 02:02 PM
thecrimulo #1
Posted 26 July 2016 - 04:02 PM
Hey there! I'm trying to make a bootloader, and I want to detect all .bmf on /dev, but line 83 gives me: "Attempt to index ? (a nil value)". I've been trying to troubleshoot the error, and I think it may be that fs.open is returning nil, but if that code gets to run, it means there is a file. Thanks in advance

local function toLines(readall)
  local t = {}
  local function helper(line) table.insert(t, line) return "" end
  helper((readall:gsub("(.-]\r?\n", helper)))
  return t
end

local function s(str, char)
  sep = sep or "%s"
  local l={}
  for str in string.gmatch(str, "(.-)("..sep..")") do
	table.insert(l,str)
  end
  return t
end


function sW(str, start)
  return string.sub(str,1,string.len(Start))==Start
end
function eW(str, ends)
  return ends=='' or string.sub(str, -string.len(ends))==ends
end

bmflist = {}
seltable = {1}

fsl = fs.list("/dev")

for _,fse in ipairs(fsl) do
  print(fse) --Debug print
  if eW(fse, ".bmf") then
	bmf = fs.open(fse, "r") -- Debug print (THIS errors)
	bmflist[fse] = {["rf"] = bmf} -- THIS errors
	print(bmf.readAll())
	bmflines = toLines(bmf.readAll())
	for line in bmflines do
	  if sW(line, "-- entryName:") then
		sline = s(line, ':')
		bmflist[fse]["en"] = sline[2]
		if sline[2] == "Shutdown" then
		  table.insert(seltable, 2)
		else table.insert(seltable, 0) end
	  elseif sW(line, "-- description:") then
		sline = s(line, ':')
		bmflist[fse]["dc"] = sline[2]
	  elseif sW(line, "-- bmf:end") then break end
	end
  end
  bmf.close()
  term.setCursorPos(1,19)
  if bmflist == {} then error("> No .bmf files found.") end
  for k,v in bmflist do if v["en"] == nil then error("> .bmf file not registered.") end end
end
Lupus590 #2
Posted 26 July 2016 - 05:44 PM
the error should give a file name too, which file name did it give?

also the code you gave doesn't have 80+ lines.

if all else fails then add a few print statements throughout your code, the error is between the last one which gets printed and the first one which didn't
Meit #3
Posted 26 July 2016 - 05:55 PM
Happened with me, in my disk lock here is the fix
use shell.resolve
Like this:
resolvedPath = shell.resolve("hellothere.lua")
hwnd = fs.open(resolvedPath, "r")
if hwnd then
dataContains = hwnd.readAll()
hwnd.close()
print("Recieved: " ..dataContains ..".")
else
print("Failed to open the file!")
error()
end
thecrimulo #4
Posted 26 July 2016 - 10:54 PM
The code has a filename and has 100+ lines, just want to keep it secret. Thanks Meit! The Code worked, but now I have another problem.

bmflines = toLines(bmf.readAll())

for line in bmflines do -- Error here
          if sW(line, "-- entryName:") then
                sline = s(line, ':')
                bmflist[fse]["en"] = sline[2]
                if sline[2] == "Shutdown" then
                  table.insert(seltable, 2)
                else table.insert(seltable, 0) end
          elseif sW(line, "-- description:") then
                sline = s(line, ':')
                bmflist[fse]["dc"] = sline[2]
          elseif sW(line, "-- bmf:end") then break end
        end

(Same code as above, full code above). Now it says Attempt to call table…
Lupus590 #5
Posted 27 July 2016 - 12:04 AM
Attempt to call table means that you are using a table as a function which doesn't have a meta-method for that (don't worry if you don't understand that last bit)

for x in y do expects y to be an iterator function, try looking at this: https://www.lua.org/pil/7.3.html
Edited on 26 July 2016 - 10:04 PM
Dog #6
Posted 27 July 2016 - 12:31 AM
Instead of creating bmflines and trying to iterate on that, I think this would achieve what you want. However I'm not sure if it'll work on a file that is already opened with a handle (haven't ever tried that)…

for line in io.lines(fse) do
  ...
end