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

Help With Arguments

Started by pamiller3, 03 June 2013 - 01:53 PM
pamiller3 #1
Posted 03 June 2013 - 03:53 PM
I have a program that I am needing to make. I wish to design one that you simply type "<program> <depth>" and the program will dig that many squares. I am not finding much assistance in this other places and I am about to give up.

Thank you for any assistance,
pamiller3
Lyqyd #2
Posted 03 June 2013 - 03:57 PM
Split into new topic.
Kingdaro #3
Posted 03 June 2013 - 04:06 PM
If you only need to capture one argument, this is how I'd do it:

local depth = ...

The … represents all of the words that the user enters after the program name. In your case, you would need to convert it to a number and then check if it's a valid number before continuing.

local depth = tonumber(...)

if depth == nil then
  print 'Invalid depth'
  return  -- "this return statement stops the program right then and there."
end

-- "your digging code"

Note that this can't be inside a function, and therefore, this wouldn't work:

function dig()
  local depth = tonumber(...)

  if depth == nil then
    print 'Invalid depth'
    return
    -- "this return statement works differently now"
    -- "it just stops the function instead of the entire program"
  end

  -- "your digging code"
end
dig()

print 'Digging completed.' -- "so this text would still get printed, even if the user put an invalid number."

But you could also just pass the arguments to the dig function, like so:

function dig(depth)
  if depth == nil then
    print 'Invalid depth'
    return
  end

  -- "your digging code"
end
dig(tonumber(...))
GopherAtl #4
Posted 03 June 2013 - 04:57 PM
it's a minor point, perhaps, but using … without {} doesn't make it return everything, it just returns as if it were a comma-separated series. This will work exactly as expected if you say "local myVar=…" as only the first value is captured and the rest get thrown away. If you pass it to a function, like "tonumber(…)", however, any additional values will get passed as additional arguments to that function. In the case of tonumber, this will earn you a "bad argument: number expected, got string" error, as the optional second argument to tonumber must be a number, if present, and … is always a list of strings.

Even if you're only taking one argument, it's best to stick with the convention of catching the whole array, and access the first argument in that array, like this:

  --grab args to array
  local tArgs = { ... }
  --convert first argument to a number
  local dist=tonumber(tArgs[1])

If you actually want the entire line after the command as a single string (obviously not the case for the OP, but for completeness), you can use table concatenation, like so…


local argStr = table.concat( { ... }, " ")
pamiller3 #5
Posted 03 June 2013 - 11:36 PM
Ok I am afraid I am more newbie than I thought. I have this program and it fails:

local depth = tonumber(…)

function dig(depth)

if depth == nil then
print 'INVALID'
return
end

do turtle.digdown()
do turtle.down()

end
dig(to number(…))
Kingdaro #6
Posted 04 June 2013 - 01:12 AM
I only said you could use a function, and in this case, it wouldn't work very well. Aside from that, there are some other general errors with the script, such as

do turtle.digdown()
do turtle.down()

There shouldn't be a "do" and "digdown" should be "digDown". With that said, here's what your program should look like:

local depth = ...
depth = tonumber(depth)

if depth == nil then
  print 'INVALID'
  return
end

turtle.digDown()
turtle.down()

And for future reference, the next time you say that a program of yours fails, it would be helpful if you provided the error that was thrown.




In response to GopherAtl, it actually is possible to get multiple variables from … on one line, easily.

local x, y, z = ...

Your second point about tonumber throwing an error, that was admittedly a mistake on my part, but is easily fixed by converting the number after declaration, or if you only need one argument, passing 10 to the tonumber() function on argument capture.
Lyqyd #7
Posted 04 June 2013 - 01:49 AM
In response to GopherAtl, it actually is possible to get multiple variables from … on one line, easily.

This was already addressed. Emphasis mine:

it's a minor point, perhaps, but using … without {} doesn't make it return everything, it just returns as if it were a comma-separated series.
Kingdaro #8
Posted 04 June 2013 - 02:11 AM
The way he stated it made it seem as though he believed the case only worked when capturing arguments to one variable.
pamiller3 #9
Posted 04 June 2013 - 09:52 AM
Alright I corrected the program to look as you said, Doctor, but it now only digs down one block and will not move down at all to continue. I am not certain where to go from here.
Bomb Bloke #10
Posted 04 June 2013 - 10:21 AM
If the turtle doesn't move down, it may not be fuelled.

If the turtle does move down but doesn't continue after that, you probably haven't constructed a loop to dig to your target depth yet. "for" loops are ideal for this sort of thing.

for i=1,depth do
  turtle.digDown()
  turtle.down()
end

The first time the "for" block is executed, "i" is set to one. At the end of the block, "i" is incremented to by one to a total of two, and the code runs again. This continues over and over until "i" would exceed the value of "depth", at which point your program continues on from the bottom of the "for" block.