开发者

AppleScript - StackOverflow error

I just started using applescript today, and heard about subroutines. So I decided to write a little test program that takes a number, increments it by 9, subtracts 27, divides by 3, and then returns the resu开发者_开发知识库lt. Only it doesn't return the result; it returns a StackOverFlow error instead. What is a StackOverFlow error?

The program compiled correctly, and I don't know what is wrong. Like I said, I'm very new to applescript. Here is the code that I'm running:

calculate_result(text returned of (display dialog "Enter a number:" default answer ""))

on calculate_result(this_result)
    set this_result to this_result + 9
    set this_result to this_result - 27
    set this_result to this_result / 3
    return calculate_result(this_result)
end calculate_result


An excerpt from an answer to a similar question...

Parameters and local variables are allocated on the stack (with reference types the object lives on the heap and a variable references that object). The stack typically lives at the upper end of your address space and as it is used up it heads towards the bottom of the address space (ie towards zero).

Your process also has a heap, which lives at the bottom end of your process. As you allocate memory this heap can grow towards the upper end of your address space. As you can see, there is the potential for the heap to "collide" with the stack (a bit like techtonic plates!!!).

A Stack Overflow error means that the stack (your subroutine) overflowed (executed itself so many times that it crashed). Stack Overflow errors usually result from a bad recursive call (in the case of AppleScript, a bad subroutine call).

In general, if your subroutines return values, make sure that value is not the subroutine name. Otherwise the stack will overflow, crashing your program (if the return statement is not inside a try block). Just change this:

return calculate_result(this_result)

...to this

return this_result

...and you should be good to go!

In some cases it is fine to return the subroutine name, but only if there is a terminating condition. For example, if a user entered an invalid number, the subroutine could rerun itself, but only if the number was invalid (shown below):

on get_input()
    set this_number to null
    try
        set this_number to the text returned of (display dialog "Please enter a number:" default answer "") as number
    on error --the user didn't enter a number and the program tried to coerce the result into a number and threw an error, so the program branches here
        return get_input()
    end try
    return this_number
end get_input

In the above case, the terminating condition occurs when a user enters an actual number. You can usually tell when a program will throw a Stack Overflow error because there is no terminating condition.

I hope this information helps!


In "calculate_result", the last line is calling "calculate_result" again. Change the line to:

return (this_result)

The last line in the subroutine is just calling the subroutine again, which calls the subroutine again, which calls the subroutine again, which calls the subroutine again, which calls the subroutine again...

I think you get the idea - the AppleScript, as you've written it - crashes because it just keeps calling itself, and eventually runs out of memory, hence triggering the stack overflow error.

A stack overflow error happens anytime a program runs out of a certain kind of memory space - it's not specific to AppleScript - it can happen in any programming language. See this answer for a more in-depth explanation of a stack overflow error is:

( What is a stack overflow? )


return calculate_result(this_result)

You are recursively calling the subroutine again passing this_result to it and the called function in turn calls the sub-routine and so on. Variables, return address of the function etc., resides on stack. And due to the recursive nature of the sub-routine the stack overflows.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜