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

FS API h.readAll() returns 'attempt to index ? (a nil value)'

Started by Rsstn, 21 February 2013 - 02:44 AM
Rsstn #1
Posted 21 February 2013 - 03:44 AM
Hi guys, haven't been here in a while!
I am starting my own email programs for a server with friends and have started by giving them an easy way to change what side the modem is attached to (the don't know Lua).
I started with this: http://pastebin.com/4gsvLThm (The pastebin link is better because the colour is correct)

Spoiler
function clearS()
term.setCursorPos(1,1)
term.clear()
end

function writeToFile(data)
h = fs.open("EmailData/ModemData", "w")
h.write(data)
h.close()
end


if fs.isDir("EmailData") == false then --Make sure the directory exists. I want the file in a directory so that the files won't show up when the user displays the list of programs on the PC.
fs.makeDir("EmailData")
end

clearS()
h = fs.open("EmailData/ModemData", "r")
modemSide = h.readAll() -- Find out what the side is before changes. This is where the error is.
h.close()

while true do --Loop so that they are asked until they provide a valid answer.
if modemSide == "left" or modemSide == "right" or modemSide == "top" or modemSide == "bottom" or modemSide == "back" or modemSide == "front" then
print("The modem is currently set to be on the " ..  modemSide .. " of the computer.")
print("Would you like to change this?")
print("'Y' or 'N'? ")
event, param1 = os.pullEvent("key")
if param1 == 109 then
clearS()
print("The modem side will not be changed.")
sleep(2)
clearS()
break
elseif param1 == 121 then
clearS()
while true do --Loop so that they are asked until they provide a valid answer.
print("What side should the monitor be changed to?")
print("Please select a number:")
print("[1] Left")
print("[2] Right")
print("[3] Top")
print("[4] Bottom")
print("[5] Front")
print("[6] Back")
print("[0] Cancel")
local event, param2 = os.pullEvent("key") --Get the user input...
if param2 == 49 then
s = "left"
break
elseif param2 == 50 then --And compare it to the ASCII codes for those keys.
s = "right"
break
elseif param2 == 51 then
s = "top"
break
elseif param2 == 52 then
s = "bottom"
break
elseif param2 == 53 then
s = "front"
break
elseif param2 == 54 then
s = "back"
clearS()
break
elseif param2 == 48 then
clearS()
print("Cancelling...")
sleep(1.5)
else
clearS()
print("That is not a valid selection...")
sleep(1.5)
end
end
clearS()
writeToFile(s) -- Set the side to what the user wants.
print("You have sucessfully changed the side of the modem to: " .. s)
sleep(2)
break
else
clearS()
print("That's not a valid answer...")
sleep(1.5)
clearS()
end
elseif modemSide == nil then
writeToFile("right") -- Set the default side.
end
end

The error I get is:
FILENAME:19: attempt to index ? (a nil value)

I've seen this error many a time before, but I just can't work out what's going wrong. It seems that 'h.readAll()' is returning nil, and I can't work out why. I've done this before and not had trouble, and tried using 'h.readLine()' too.
This is all correct according to the wiki, but maybe it's just that I'm out of practice in Lua.
(and yes I know it could be neater, but I just want to get it working for now!)

Thanks in advance,
Ross.
Lyqyd #2
Posted 21 February 2013 - 04:19 AM
Check that the file you are trying to open exists.
LBPHacker #3
Posted 21 February 2013 - 04:20 AM
That means h is nil. Make sure that the file you're trying to open does actually exist.

EDIT Ninja'd… nevermind…
Rsstn #4
Posted 21 February 2013 - 04:35 AM
Ah, ok that might be it. I forgot the code to write the file comes after the code to read it!
I'll assume that's the problem and give it a go later. Thanks for your help guys!
theoriginalbit #5
Posted 21 February 2013 - 04:38 AM
to prevent it in the future do this


h = fs.open("EmailData/ModemData", "r")
if not h then error("Could not open the file for read") end
modemSide = h.readAll()
h.close()


that way when you get an error in the future it makes a little more sense.
remiX #6
Posted 21 February 2013 - 04:45 AM
to prevent it in the future do this


h = fs.open("EmailData/ModemData", "r")
if not h then error("Could not open the file for read") end
modemSide = h.readAll()
h.close()


that way when you get an error in the future it makes a little more sense.


h = assert(fs.open('EmailData/ModemData', 'r'), "Could not open the file for read")
theoriginalbit #7
Posted 21 February 2013 - 05:05 AM
h = assert(fs.open('EmailData/ModemData', 'r'), "Could not open the file for read")
Also works yes. would think i would have used that given the error handling tutorial I did, and recently updating it with more on assert. wonder why i didn't.
Rsstn #8
Posted 21 February 2013 - 05:09 AM
Ok, here is my new code: http://pastebin.com/wx6ssA7X
But whenever I run the code, the computer goes blank (shutting down? crashing?)
When I right-click on the PC again, it boots up like normal with 'CraftOS 1.5'.
What's going on here?
PixelToast #9
Posted 21 February 2013 - 05:13 AM
its most likely too long without yeilding
because your yeild is encased in

if modemSide == "left" or modemSide == "right" or modemSide == "top" or modemSide == "bottom" or modemSide == "back" or modemSide == "front" then
LBPHacker #10
Posted 21 February 2013 - 05:21 AM
its most likely too long without yeilding

In other words (sorry Pixel, I don't think that's very clear) you have to swap the "if modemSide" and the "while true do". Cuz if the IF returns false, it just keeps checking modemSide in an infinite loop.
PixelToast #11
Posted 21 February 2013 - 05:26 AM
that means there is another problem, modemSide isnt any of those sides
Rsstn #12
Posted 21 February 2013 - 05:39 AM
Ok, I found that it was stopping because my program did not yeild, and the screen stayed blank because there was no 'else' part of the if statement. (wasn't supposed to be needed!)
Now I got to find out why the ASCII codes arn't correct…

EDIT: Ah, you got there first!
Rsstn #13
Posted 21 February 2013 - 05:41 AM
But the 'write()' line near the top should have sorted that out and set it to the default (right) side…
PixelToast #14
Posted 21 February 2013 - 05:44 AM
idk, aslong as it dosent error now you sould be fine