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

Request System gets error Attempt to index ? (a nil value) [SOLVED]

Started by Revan, 04 April 2013 - 06:52 AM
Revan #1
Posted 04 April 2013 - 08:52 AM
Hello everyone,

I've been trying to make a request system for my storage facility, so that when I'm at the front door, I can just request a couple items I need from the computer and they get from their respective chests transported to the chest besides the computer.

I've made 2 programs for this (1 for the requesting computer and 1 for the retrieving one):

Request prog: http://pastebin.com/cAWaB6HY
Retrieve prog: http://pastebin.com/BgfEddL9

Now the error I get when I request something is: Request:68: attempt to index ? (a nil value).

What am I forgetting? And how can I add more retriever computers? Like for now, I've got 1 retriever computer with 32 connections from it. I've got another 4 computers that need to be hooked up the same way, but what is the easiest way to do this?

I've looked through the tutorials I could find, but I haven't been able to come up with a working solution yet..

Btw, I'm running this on a tekkit classic server if this makes any difference. (version 1.33 of CC on it)
Edited on 04 April 2013 - 07:28 AM
Engineer #2
Posted 04 April 2013 - 09:09 AM
Uhhm.. Why are you comparing an integer with a string? :S
That is the problem, you can only do (from my knowledge):

-- Basically you do this:
if type(var1) == type(var2) then
    if var1 == var2 then
       -- stuff
    end
end

So you can only compare a string with a string, an integer with an integer etc.

Real pro's out there, correct me if Im wrong
Telokis #3
Posted 04 April 2013 - 09:12 AM
Hi !
You have a syntax error in your table declaration.

You are doing this (I simplify to be clearer)

itemList =
   {  [1]=   { [1]="Stone", [2]="Cobblestone", },
   {  [2]=   { [1]="",  [2]="",   }  }  }

You put too much ',' in your declaration. It should be like that :


itemList =
   {  [1]=   { [1]="Stone", [2]="Cobblestone" }, [2]=   { [1]="",  [2]=""   }  }

Do you see why I do this ?
Revan #4
Posted 04 April 2013 - 09:16 AM
Hi !
You have a syntax error in your table declaration.

You are doing this (I simplify to be clearer)

itemList =
   {  [1]=   { [1]="Stone", [2]="Cobblestone", },
   {  [2]=   { [1]="",  [2]="",   }  }  }

You put too much ',' in your declaration. It should be like that :


itemList =
   {  [1]=   { [1]="Stone", [2]="Cobblestone" }, [2]=   { [1]="",  [2]=""   }  }

Do you see why I do this ?

Perfect :D/> This made it work. Thank you so much.. Do you have any idea how I could add more computers to this network though?
Telokis #5
Posted 04 April 2013 - 09:16 AM
Uhhm.. Why are you comparing an integer with a string? :S
That is the problem, you can only do (from my knowledge):

-- Basically you do this:
if type(var1) == type(var2) then
	if var1 == var2 then
	   -- stuff
	end
end

So you can only compare a string with a string, an integer with an integer etc.

Real pro's out there, correct me if Im wrong

As just said Engineer, you have a type problem. If you want to initialize a variable to a default value, use nil instead of 0. 0 is a number while nil is… nil ! (Meaning the variable doesn't contains anything)

Moreover, if you type enter without writing any word in read, it will return an empty string (""), it won't return nil. Keep it in mind if you want to track errors.
Engineer #6
Posted 04 April 2013 - 09:21 AM
Just for the future:

If you want to check a value with content:

if value then -- Without something it is something like == true, but not really
end

if not value then -- This is something like == false, but then a bit more complex. Just accept that it is better.
end

Also you can use not for functions;

if turtle.forward() then
   print("I moved forward! :D/>/>")
elseif not turtle.forward()  then
   print("I could not move forward :c")
end

Of course an else would be more practical in this case, but you get hopefully the point
Revan #7
Posted 04 April 2013 - 09:28 AM
Yes, I've got the point. Thanks for the help. Can't believe I overlooked something so, well, simple for the solution. Thanks again.
Telokis #8
Posted 04 April 2013 - 09:55 AM
Hi !
You have a syntax error in your table declaration.

You are doing this (I simplify to be clearer)

itemList =
   {  [1]=   { [1]="Stone", [2]="Cobblestone", },
   {  [2]=   { [1]="",  [2]="",   }  }  }

You put too much ',' in your declaration. It should be like that :


itemList =
   {  [1]=   { [1]="Stone", [2]="Cobblestone" }, [2]=   { [1]="",  [2]=""   }  }

Do you see why I do this ?

Perfect :D/> This made it work. Thank you so much.. Do you have any idea how I could add more computers to this network though?

First, I see you do


rednet.send(3, Object)
sleep(0.2)
rednet.send(3, Amount)

You should do something like this to be more flexible :


rednet.send(3, textutils.serialize({Object, Amount}))

This line will create a table where the first entry will be your object and the second will be the amount. To receive such a data, you have to do something like


local id, temp = rednet.receive()
local tDatas = textutils.unserialize(temp)
print(tDatas[1]) -- will show the value of Object
print(tDatas[2]) -- will show the desired amount

If you want to manage several computers, use rednet.broadcast instead of rednet.send it will send your message to all listening computers.
Once your retriever(s) computer(s) received a message, he reads Object and know if he has to move or not.

Example :

You have 2 retrievers. The first only works for CobbleStone and the second only works for Wood.

You ask {"CobbleStone", 5}.

Each computer will receive the message. The wood manager won't do anything because he doesn't manage CobbleStone and the CobbleStone manage will bring you 5 CobbleStone.

I don't know if I was clear so, if you don't understand, let me know and I'll explain again.