Declaring additional local variables prevents script from running

I have been enjoying Script Debugger. However, I have encountered a frequent issue. After declaring additional local variables and compiling, the script does not run. It does not get to the “setting breakpoint” stage. Variables can be boolean, lists, strings. My script is very long. When I cut out and simplify the code, I don’t get the error. Thoughts?

I suspect you’ve answered your own question — it sounds like your script is too long. AppleScript starts behaving strangely when scripts get too big.

Thank you for your reply.

The 2,200-line script with all local declarations works fine in Script Editor. I infer from this experiment that the problem is not with AppleScript but with Script Debugger.

It would be useful to know, if disappointing, that many people have found that Script Debugger can’t handle moderately long scripts.

A 2200-line script is not “moderately” long – it’s long. AppleScript has relatively low limits, certainly compared with other languages.

Script Debugger’s debugging mode has a considerably lower limit because it has to add a significant amount of extra code to make debugging work. And it probably has a fraction smaller limit with debugging off simply because it has a bigger scripting dictionary.

But if you’re approaching the limit that will compile, there’s a good chance you will get problems when running the code.

Shane, I have NOT experienced this problem, but what about long scptd files that are a Script Library? Will they have the same issue when the number of lines approach this 2000 limit?

It would be good to know there is a practical limit on number of lines for Script Dictionary, so we can plan and design them properly.

@Shane. I was typing the same when JMichel replied.

Thank you for your patient response. Do you have a rule of thumb for a limit to script length in a single .scpt file? If I create a bundle with multiple .scpt files, do the number of .scpt files create similar problems or …?

This is a related issue:

When you approach AppleScript’s limits all kinds of strange things begin to happen. Too many comments can make things worse. Too many unique variable, handler and script object names can make things worse. Code that is nested too deeply can make things worse.

Even if your code works in the Script Editor, you are nearing AppleScript’s limits and these problems will bite when you least expect it.

In my response to the post quoted above, I suggest a limit of 2000-2500, but <2000 lines is a better rule of thumb.

1 Like

Unfortunately, the only way of discovering these limits is by breaking them, and number of lines really a very rough gauge — what’s in the lines is what really matters. For an individual script library, you certainly don’t want to approach the rule-of-thumb limit, but to be honest, I’m not sure if there’s some sort of cumulative limit in terms of script-plus-loaded-libraries.

FWIW, I try to limit libraries to less than 800 lines, although I have crept slightly over that at times.

1 Like

One other thing to note: scripts saved run-only have a bit more overhead. (As in spare overhead.)

Super helpful! Now, the fun of refactoring!

I have an bunch of script libraries which are each about 3.000-4.000 lines long. No problems so far.

Scale is not really what AppleScript is built for – the stack, for one thing, is shallow. We get:

~ $ osascript ~/recursionDepth.applescript
Recursion limit encountered at level 502

from:

on run
    recursionDepth()
end run

-- recursionDepth :: () -> IO String
on recursionDepth()
    script go
        on |λ|(i)
            try
                |λ|(1 + i)
            on error
                "Recursion limit encountered at level " & i
            end try
        end |λ|
    end script
    
    go's |λ|(0)
end recursionDepth

Which is symptomatic of generally constrained resource.

AppleScript is very useful for small bits of glue, but for any kind of scale it’s likely to be more stable to use the osascript interface from JS, which, for example, yields:

~ $ osascript -l JavaScript ~/recursionDepthJS.scpt
Recursion level 31721  ->  Maximum call stack size exceeded.

from:

(() => {
    'use strict';

    const recursionDepth = () => {
        const go = i => {
            try {
                go(1 + i)
            } catch (e) {
                console.log(
                    'Recursion level', 
                    i, ' -> ', e.message
                )
            }
        };
        return go(0);
    };

    return recursionDepth();
})();

Leaving a bit more room to breathe, and more libraries (and built-in functions) to draw on.

(Script Debugger remains very useful – for exploring osascript APIs – regardless of whether you happen to be writing in AS or JS).

2 Likes