AppleScript - ошибка StackOverflow - PullRequest
       16

AppleScript - ошибка StackOverflow

0 голосов
/ 13 августа 2011

Я только сегодня начал использовать applecript и слышал о подпрограммах. Поэтому я решил написать небольшую тестовую программу, которая принимает число, увеличивает его на 9, вычитает 27, делит на 3 и возвращает результат. Только это не возвращает результат; вместо этого он возвращает ошибку StackOverFlow. Что такое ошибка StackOverFlow?

Программа скомпилирована правильно, и я не знаю, что не так. Как я уже сказал, я очень новичок в applecript. Вот код, который я запускаю:

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

Ответы [ 3 ]

3 голосов
/ 13 августа 2011

Отрывок из ответ на аналогичный вопрос ...

Параметры и локальные переменные размещаются в стеке (со ссылочными типами объект живет в куче, а переменная ссылается на этот объект). Стек обычно располагается в верхнем конце вашего адресного пространства и по мере его использования он направляется к нижней части адресного пространства (т. Е. К нулю).

У вашего процесса также есть куча, которая находится в нижней части вашего процесса. По мере выделения памяти эта куча может увеличиваться в направлении верхнего края вашего адресного пространства. Как видите, существует вероятность того, что куча «столкнется» со стеком (что-то вроде техтонических пластин !!!).

Ошибка переполнения стека означает, что стек (ваша подпрограмма) переполнен (выполнялся сам столько раз, что падал). Ошибки переполнения стека обычно возникают из-за плохого рекурсивного вызова (в случае AppleScript - неправильного вызова подпрограммы).

Как правило, если ваши подпрограммы возвращают значения, убедитесь, что значение не является именем подпрограммы. В противном случае стек переполнится, что приведет к сбою вашей программы (если оператор return находится не внутри блока try). Просто измените это:

return calculate_result(this_result)

... к этому

return this_result

... и тебе надо идти!

В некоторых случаях можно возвратить имя подпрограммы, но только если есть условие завершения. Например, если пользователь ввел недопустимый номер, подпрограмма может перезапустить себя, но только в том случае, если номер недействителен (показано ниже):

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

В вышеприведенном случае условие завершения возникает, когда пользователь вводит фактическое число. Обычно вы можете сказать, когда программа выдаст ошибку переполнения стека, потому что нет завершающего условия.

Надеюсь, эта информация поможет!

2 голосов
/ 13 августа 2011

В "Calculate_result" последняя строка снова вызывает "Calculate_result".Измените строку на:

return (this_result)

Последняя строка в подпрограмме просто снова вызывает подпрограмму, которая снова вызывает подпрограмму, которая снова вызывает подпрограмму, которая снова вызывает подпрограмму, который снова вызывает подпрограмму ...

Я думаю, что вы поняли - AppleScript, как вы его написали, - падает, потому что он просто продолжает вызывать себя, и в конечном итоге не хватает памяти, следовательно, вызываяошибка переполнения стека.

Ошибка переполнения стека возникает всякий раз, когда программе не хватает определенного типа пространства памяти - это не относится к AppleScript - это может происходить на любом языке программирования.См. Этот ответ для более подробного объяснения ошибки переполнения стека:

( Что такое переполнение стека? )

2 голосов
/ 13 августа 2011
return calculate_result(this_result)

Вы рекурсивно вызываете подпрограмму, снова передавая ей this_result, и вызываемая функция в свою очередь вызывает подпрограмму и так далее.Переменные, адрес возврата функции и т. Д. Находятся в стеке.А из-за рекурсивного характера подпрограммы стек переполняется.

...