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

[Lua][Error][Turtle] attempt to call nil

Started by LetsDark, 30 December 2012 - 01:11 AM
LetsDark #1
Posted 30 December 2012 - 02:11 AM
Hello, guys!

I com from Germany and I know my english is not so god.
I hope you anderstand what I mean.

I try to make a turtle program what mine and find all the recurcen in the strip.

I make this, but it diden't work.

path = 50

local function checkFuel()
  if turtle.getFuelLevel() < 20 then
    turtle.select(16)
    turtle.refuel(1)
  end
end

local function forward()
  turtle.dig()
  turtle.forward()
  turtle.select(1)
  turtle.placeDown()
  turtle.digUp()
  checkFuel()
end

local function compareDown()
  checkFuel()
  turtle.select(1)
  if not turtle.placeDown() then
    turtle.select(15)
    if not turtle.compareDown() then
	  turtle.select(14)
	  if not turtle.compareDown() then
	    turtle.select(13)
	    if not turtle.compareDown() then
		  rMineDown()
	    end
	  end
    end
  end
end

local function compare()
  checkFuel()
  turtle.select(1)
  if not turtle.place() then
    turtle.select(15)
    if not turtle.compare() then
	  turtle.select(14)
	  if not turtle.compare() then
	    turtle.select(13)
	    if not turtle.compare() then
		  rMine()
	    end
	  end
    end
  end
end

local function compareUp()
  checkFuel()
  turtle.select(1)
  if not turtle.placeUp() then
    turtle.select(15)
    if not turtle.compareUp() then
	  turtle.select(14)
	  if not turtle.compareUp() then
	    turtle.select(13)
	    if not turtle.compareUp() then
		  rMineUp()
	    end
	  end
    end
  end
end

local function rMineDown()
  turtle.digDown()
  turtle.down()
  compare()
  compareDown()
  turtle.turnLeft()
  turtle.compare()
  turtle.turnLeft()
  turtle.compare()
  turtle.turnLeft()
  turtle.compare()
  turtle.turnLeft()
  turtle.up()
end

local function rMine()
  turtle.dig()
  turtle.forward()
  compare()
  compareDown()
  turtle.turnLeft()
  compare()
  turtle.turnRight()
  turtle.turnRight()
  compare()
  turtle.turnLeft()
  compareUp()
  turtle.back()
end

local function rMineUp()
  turtle.digUp()
  turtle.up()
  compare()
  compareUp()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  turtle.down()
end

for i=1,path do
  forward()
  compareDown()
  turtle.turnLeft()
  compare()
  turtle.turnRight()
  turtle.turnRight()
  compare()
  turtle.turnLeft()
end
 
turtle.up()
compare()
compareUp()
turtle.turnLeft()
turtle.turnLeft()

for i=1,path do
  turtle.forward()
  compareUp()
  turtle.turnLeft()
  compare()
  turtle.turnRight()
  turtle.turnRight()
  compare()
  turtle.turnLeft()
end
slot 16 = coal, slot 15 = stone, slot 14 = dirt, slot 13 = cobblestone, slot 1 = cobbelstone

I know I have no Gravel but this is a conzept.

When I run the program, the turtle mine forward and scan to recurces.
Redstone come on le Left side and the Programm stopt and say: "hMine:46: attempt to call nil"

I hope you can halp me to write my programm in the end ;)/>

LetsDark
zekesonxx #2
Posted 30 December 2012 - 02:16 AM
You're calling rMine() from within compare(), and then calling compare() from rMine().
LetsDark #3
Posted 30 December 2012 - 02:32 AM
Thats right. I know that.

What ne turtle find recurces, he will mine all recurces. Also he grab the block and scan for more recurces and when he dont find one he go back and set cobblestone in the hole.

Can Lua run this or not? This is my first contact with Lua, before I programm with C++
zekesonxx #4
Posted 30 December 2012 - 02:42 AM
You can't make a function run itself. It creates a endless paradox.
LetsDark #5
Posted 30 December 2012 - 02:47 AM
No!

The function compare() open rMine() when all the if's are true.

There is no paradoxon.


Edit1:

Can lua run such a program? If is no, can you give me a solution?
GopherAtl #6
Posted 30 December 2012 - 04:05 AM
Lua is compiled in a single pass, so you usually can't call a function that doesn't exist yet.

Example of the problem:


local function a()
  b() --//b doesn't exist yet, this will give the "attempt to call nil" error
end

local function b()
  print("b")
end

local function c()
  b() --//this WILL work, since b was defined first
end

now, in your case, since you're calling rMine from compare and compare from rMine, you'll have to "declare" rMine before you define compare. You can simply declare a local variable with the same name, defining the actual function later.

fixed example:

--//declare a local called 'rMine" first w
--//EDITED: ...with some dummy value. Forgot that part the first time.
local rMine=function() end

--//now define compare, which now knows how to resolve rMine
local function compare()
  --...
end

--//and now define rMine, which can call compare since it's defined already
local function rMine()
  --...
end
LetsDark #7
Posted 30 December 2012 - 04:29 AM
Ok, now I have change the code but I becam the same fault.

My code:

path = 50
local function checkFuel()
  if turtle.getFuelLevel() < 20 then
    turtle.select(16)
    turtle.refuel(1)
  end
end
local function forward()
  turtle.dig()
  turtle.forward()
  turtle.select(1)
  turtle.placeDown()
  turtle.digUp()
  checkFuel()
end
local rMineDown
local rMine
local rMineUp
local function compareDown()
  checkFuel()
  turtle.select(1)
  if not turtle.placeDown() then
    turtle.select(15)
    if not turtle.compareDown() then
	  turtle.select(14)
	  if not turtle.compareDown() then
	    turtle.select(13)
	    if not turtle.compareDown() then
		  rMineDown()
	    end
	  end
    end
  end
end
local function compare()
  checkFuel()
  turtle.select(1)
  if not turtle.place() then
    turtle.select(15)
    if not turtle.compare() then
	  turtle.select(14)
	  if not turtle.compare() then
	    turtle.select(13)
	    if not turtle.compare() then
		  rMine()
	    end
	  end
    end
  end
end
local function compareUp()
  checkFuel()
  turtle.select(1)
  if not turtle.placeUp() then
    turtle.select(15)
    if not turtle.compareUp() then
	  turtle.select(14)
	  if not turtle.compareUp() then
	    turtle.select(13)
	    if not turtle.compareUp() then
		  rMineUp()
	    end
	  end
    end
  end
end
local function rMineDown()
  turtle.digDown()
  turtle.down()
  compare()
  compareDown()
  turtle.turnLeft()
  turtle.compare()
  turtle.turnLeft()
  turtle.compare()
  turtle.turnLeft()
  turtle.compare()
  turtle.turnLeft()
  turtle.up()
end
local function rMine()
  turtle.dig()
  turtle.forward()
  compare()
  compareDown()
  turtle.turnLeft()
  compare()
  turtle.turnRight()
  turtle.turnRight()
  compare()
  turtle.turnLeft()
  compareUp()
  turtle.back()
end
local function rMineUp()
  turtle.digUp()
  turtle.up()
  compare()
  compareUp()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  compare()
  turtle.turnLeft()
  turtle.down()
end
for i=1,path do
  forward()
  compareDown()
  turtle.turnLeft()
  compare()
  turtle.turnRight()
  turtle.turnRight()
  compare()
  turtle.turnLeft()
end
 
turtle.up()
compare()
compareUp()
turtle.turnLeft()
turtle.turnLeft()
for i=1,path do
  turtle.forward()
  compareUp()
  turtle.turnLeft()
  compare()
  turtle.turnRight()
  turtle.turnRight()
  compare()
  turtle.turnLeft()
end
GopherAtl #8
Posted 30 December 2012 - 04:32 AM
whoops! sorry about that, I forgot you have to actually assign some value when you pre-declare them

Fixed line:

--//declare a local called 'rMine" first with some non-nil value.
local rMine=function() end

I edited this fix into the original post as well, for completeness.

Any value will work, as long as it's not nil, so you could've just set rMine to "", or 1, or true, instead of an empty function. I do empty functions so it's clear that the variable is a function.
LetsDark #9
Posted 30 December 2012 - 04:43 AM
Ok, now it mine, but he doesen't find de recurces and mine them.

He dig the string forward and forward…
GopherAtl #10
Posted 30 December 2012 - 05:02 AM
:facepalm: man, failtastic day for me. Just tried it and redeclaring the function actually doesn't seem to work… I would swear I've done it that way before, but it's calling the stubbed function. Fixed it by changing to this:


--//declare a local called 'rMine" first
local rMine=function() end

--//now define compare, which now knows how to resolve rMine
local function compare()
  --...
end

--//and now define rMine, which can call compare since it's defined already
rMine=function()
  --...
end

From my brief tests, clearly there are some other logic errors in your code, but that gets it calling the right functions at least!
LetsDark #11
Posted 30 December 2012 - 05:10 AM
Yas! It work and mine all recurces.

Thanks Guy! I hope you can me help when I have problems agein. ;)/>

LetsDark