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

Using pcall()

Started by Wing, 09 March 2013 - 01:41 PM
Wing #1
Posted 09 March 2013 - 02:41 PM
Hey guys, I have another question!
Does pcall return true if the function completes successfully and false if there's an error?
If so is this possible or something?


repeat
  function blahblah()
    code here.....
  end
c = pcall(blahblah())
until (c == true or false)
shell.run("something")

Thank you! It's just so I can always return to the default program when the program which is running fails or complete :D/>
MysticT #2
Posted 09 March 2013 - 02:50 PM
Yes, pcall returns true if the function ended normally, and false if there was an error. Additionally it returns any values returned by the function, or an error message in case of one.
Just some comments on the code:

until (c == true or false)
c will always be either true or false, so you don't need to check for that. Also, if you want to compare a variable against 2 values, it should be:

c == true or c == false
otherwise it will check if c equals true or false is true (wich will never be).
Another thing, if you have a program that runs another program, don't run the first one in the second. Otherwise, it will probably cause an stack overflow after some time. So, just let the program end, and it will return to the first one.
ChunLing #3
Posted 09 March 2013 - 05:58 PM
Yeah…the (c == true or false) doesn't make a lot of sense. The false only comes through if the previous argument were already false (or nil), it thus can make no difference.
Mads #4
Posted 09 March 2013 - 09:11 PM
When using pcall, you have to pass in the name of the function. So pcall(blahblah), not pcall(blahblah()). With the latter, pcall will expect the function called to return a function, which I don't think blahblah() does.

pcall returns two values by default. status and msg, like this:

local status, msg = pcall(blahblah)

If you want to pass in arguments to the blahblah function, you'd have to do this instead:

local status, msg = pcall(blahblah, arg1, arg2, ...)

If status is true, the function didn't error, and the second return-value(msg) will be equal to the first return value of blahblah. But if status is false, msg will be the error message.
So, if blahblah returned "Hello, World!", then msg would equal "Hello, World!", if status was true, and the error message if it was false.

I hope that helped.
remiX #5
Posted 09 March 2013 - 10:18 PM
Using pcall does not required the parenthesis. And with arguments you would use it like this:
pcall( sleep, 3 ) -- i've heard people say it prevents CTRL + T? is it true?
Wing #6
Posted 10 March 2013 - 12:31 PM
Thanks guys! I wanted to know so once the "repeat" was done I could return the previous program, although MysticT, I don't understand what you said at the end of your post? Knowledge is power, no?
ChunLing #7
Posted 10 March 2013 - 06:06 PM
If you have a function that calls itself, or calls another function that calls the first, or whatever, then you have a recursion. Recursion is a legitimate tool in cases where the depth of the recursion is limited, so that eventually one of the functions will end rather than calling another function. If a recursion is not limited, then the stack used to track how many layers deep the recursion runs will eventually overflow, and you'll get an error.

This also applies if you are running programs, because of how shell works. I'm not sure why Mystic thought your "something" would call this program in turn, but if it did, then you'd have a very bad recursion thing happening. So just make sure that the program something doesn't call this program.
MysticT #8
Posted 11 March 2013 - 03:32 AM
Well, he said:
It's just so I can always return to the default program when the program which is running fails or complete :D/>
so I thought he wanted to use shell.run to run the previous program (like he did on the example code).

I'll give you an example so you can understand what I say:
Program 1:

shell.run("Program 2") -- run Program 2

Program 2:

local function main()
  -- code here
end

pcall(main) -- call the main function to start the program
shell.run("Program 1") -- return to Program 1

Now, this would run the program 1, then jump to the second program, then to the first one, then to the second, then to the first, …
That would cause a stack overflow error.
I don't know if that's what you were going to do. But if it is, consider changing that.