AppleScript Editor "could not be saved"

I haven’t pinned down your problem yet, but observations:
(1) osacompile reports a little more specifically: “storage error: Internal table overflow. (-2707)”
(2) This is definitely a language internals issue, as it occurs on my very different system.
(3) I am having trouble finding the error consistently.

Model: PPC G4 Dual-800Mhz
AppleScript: 1.10.7
Browser: Safari 533.19.4
Operating System: Mac OS X (10.4)

This is then one of the cases in which seting the parent property to AppleScript, in the script in question may help. :slight_smile:

But it really only remedies the symptom, and not the cause. I think some restructuring of the data may also help, like for instance putting the data into a script object within the script, (which also should have set the parent property to AppleScript.

This is a very awkward situation, when it happens, I wish the Op good luck!

Is this post from nine years ago still relevant?!
http://macscripter.net/viewtopic.php?id=11760

Basically there is a maximum size for any AppleScript.

“There is some sort of limit to how much code I can have in the script . will report an Internal table overflow (-2707) error when trying to save the script. It compiles OK, however.”

There’s a limit to most things :wink:

The limit in AppleScript is to the number of “objects” in the script, where “objects” encompasses not just variables but also statements, identifiers, you name it. I wouldn’t be surprised if elements in long literal lists are regarded as separate “objects” in this context, and that may be pushing you over the limit.

There are a couple of workarounds you could try. if your script really uses long lists of individual characters, you should be able to rework your code to use a single string, either converting it to a list on the fly, or better still, changing how it is used. You can check if a character is in a string of characters, and its offset if need be, as easily as you can check if it’s in a list of characters, and probably more quickly.

Hello

I tested a given proposal :

I used Find/Replace to convert

local FirstCharCantBeDigit, CCAllowedChars, CS6AllowedChars

set FirstCharCantBeDigit to {"0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}
set CCAllowedChars to {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9", "€", "∞", "¢", "≠", "˜", """, "Ï€", "ø", " ", "∑", "Å“", "∂", "Æ’", "-", "Ë™", "∆", "Ëš", "-", ".", "-", "÷", "≥", "≤", "-", "-", "∫", "√", "-", "≈", "Ω", "â„¢", "¹", "º", "fi", "fl", "¡", "'", """, "∏", "°", "ž", "Å’", "", "˘", "Ëœ", "ˆ", "ı", "â—Š", "Ÿ", "ü"}
set CS6AllowedChars to {"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n", "o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z", "0", "1", "2", "3", "4", "5", "6", "7", "8", "9"}

into


local FirstCharCantBeDigit, CCAllowedChars, CS6AllowedChars

set FirstCharCantBeDigit to text items of "0123456789"
set CCAllowedChars to text items of "abcdefghijklmnopqrstuvwxyz0123456789€∞¢â‰ ˜"πø ∑œ∂ƒ-˙∆˚-.-÷≥≤--∫√-≈Ω™¹ºï¬ï¬‚¡'"∏°žÅ’˘˜ˆı◊Ÿü"
set CS6AllowedChars to text items of "abcdefghijklmnopqrstuvwxyz0123456789"

In fact I did the trick on your complete script (plus one trio added to check that it can’t be saved).
The edited version saved flawlessly.
I applied Copy paste so that the set something trio was embedded twice the time it is in your origional script and this time it saves again flawlessly.
With 244 copies of the trio it saves again flawlessly.

It seems that with that we are on the good track.

KOENIG Yvan (VALLAURIS, France) samedi 28 septembre 2013 10:26:08

Hi Yvan.

Those elements should of course be ‘characters of .’ unless AppleScript’s text item delimiters are explicity set to “” or to {“”} first. They shouldn’t be assumed to be at their default setting.

Hello Nigel

Of course you are right. I made the changes too quickly.

KOENIG Yvan (VALLAURIS, France) samedi 28 septembre 2013 11:03:34

One other point: whether the error is triggered or not when saving manually can depend on whether you’re saving as run-only – for run-only scripts the threshold is a bit higher, because without the source there are fewer objects to be saved.

So in theory you could probably copy your script into a .applescript script, where autosaving is not a problem because it will only autosave as text, compile there, and export run-only, with more chance of success.

But I really wouldn’t advise that except in desperate circumstances…

A potential time-waster here is that we’re discussing a demo script which happens to contain several iterations of three list-setting lines. We’ve no idea what’s in the script which actually needs the cure.

However, we seem to be agreed from previous experience that the probable cause of the problem is data bloat and that Dan should be looking at ways to reduce the amount of data which AppleScript (at run time) and AppleScript Editor (during editing) try to store in the script file. The amount of data flying around while the script’s actually running shouldn’t be a problem as long as it’s not being held in persistent variables when the script exits.

Strategies (mostly suggested above) include:

¢ Don’t compile bulky objects as literal values into the script, but use less bulky alternatives, commands, and references to set them up when the script runs.
¢ Alternatively, store them somewhere other than in the script.
¢ Prefer local variables where possible so that their contents aren’t automatically saved to the script file when the script exits.
¢ Replace bulky values with minimal-bulk ones in persistent variables which don’t need to persist ditto.
¢ Don’t replicate data which could be shared or reused.

Hello Nigel

When I use properties, I define them with empty values.
I set their values when entering the script and reset the empty values when leaving the script.

property FirstCharCantBeDigit : {}
property CCAllowedChars : {}
property CS6AllowedChars : {}

set FirstCharCantBeDigit to characters of "0123456789"
set CCAllowedChars to characters of "abcdefghijklmnopqrstuvwxyz0123456789€∞¢â‰ ˜"πø ∑œ∂ƒ-˙∆˚-.-÷≥≤--∫√-≈Ω™¹ºï¬ï¬‚¡'"∏°žÅ’˘˜ˆı◊Ÿü"
set CS6AllowedChars to characters of "abcdefghijklmnopqrstuvwxyz0123456789"

set FirstCharCantBeDigit to {}
set CCAllowedChars to {}
set CS6AllowedChars to {}

In fact I replicated 1 090 times the trio building the lists and was able to save the compiled script which reached 945 653 bytes. Of course it saved too after running because the properties were cleared on exit.
With an extraneous trio I was unable to save.

It seems that I reached the size limit for a compiled script.
Isn’t it a sufficient size ?

KOENIG Yvan (VALLAURIS, France) samedi 28 septembre 2013 18:23:19

Hello.

Now if you have anything that relates to that amount of data in a real script, so that it won’t compile, then you can either split your script into several scripts, and call that script, if the state that it is made for occurs, or read in data from a file as necessary, for instance paragraph 3 or something, which would then contain the characters, or whatever, for that given circumstance.

Hello.

Try running the script below, close it, and then open it and rerun it while you watch the log window.
You will see that local variables are not stored between runs at the root level of a script.

local a
try
	log a
on error
	log "a is undefined"
end try
set a to 5

Hello.

It’s sort of confusing this, a variable, either declared at the top level of a script, or in a script’s run handler is a global variable, in the sence that it’s value will be stored like a property.
Now, this isn’t exactly the same as a global variable, as a global variable is visible to scripts that you load after you have declared the variable global. But a variable declared global, is also stored like a property!

So a variable declared global, is more kind of an universal variable, than just a global. :slight_smile:

Hello kel

In your sample, a is not declared as local. In fact, it is a global as every variable defined in the main script.

Try to run this one twice.


property i : 0
local a
if i = 0 then
	set i to 1
	set a to {1, 2, 3}
end if
a

This time, a is defined as local.
At first run it’s set to {1,2,3} and, at second run the local is undefined and you will got the logical error message :
error “La variable a n’est pas définie.” number -2753 from “a”

There is a sufficient number of oddities in AppleScript, there is no need to invent ones.

KOENIG Yvan (VALLAURIS, France) dimanche 29 septembre 2013 09:35:35

Hi Yvan.

In a situation where a global scope is needed but values don’t need to persist between runs of the script, I’d personally use globals instead of properties. It makes little difference to what actually happens, but the intention’s clearer:

global FirstCharCantBeDigit, CCAllowedChars, CS6AllowedChars

set FirstCharCantBeDigit to characters of "0123456789"
set CCAllowedChars to characters of "abcdefghijklmnopqrstuvwxyz0123456789€∞¢â‰ ˜"πø ∑œ∂ƒ-˙∆˚-.-÷≥≤--∫√-≈Ω™¹ºï¬ï¬‚¡'"∏°žÅ’˘˜ˆı◊Ÿü"
set CS6AllowedChars to characters of "abcdefghijklmnopqrstuvwxyz0123456789"

set FirstCharCantBeDigit to {}
set CCAllowedChars to {}
set CS6AllowedChars to {}

WIth regard to globals, I’m a fan of the fact that if they’re declared only in the handlers where they’re used, instead of at the top of the script, their “globality” only applies in those handlers and the ‘run’ handler:

log aHandler() -- aHandler sets the value of a global declared in it.
log bHandler() -- bHandler knows about it because it's declared there too.
log FirstCharCantBeDigit -- The run handler knows about globals anyway.
log cHandler() -- cHandler doesn't know about it because the it's not declared there.

on aHandler()
	global FirstCharCantBeDigit
	
	set FirstCharCantBeDigit to "Hello"
	return FirstCharCantBeDigit
end aHandler

on bHandler()
	global FirstCharCantBeDigit
	
	return FirstCharCantBeDigit
end bHandler

on cHandler()
	return FirstCharCantBeDigit
end cHandler

The above is the same as declaring ‘FirstCharCantBeDigit’ global at the top of the script and explicitly declaring it local in ‘cHandler’.

Declaring a global in an explicit ‘run’ handler has the same effect as not declaring it there. It’s still a global, but its scope only only extends to other handlers where it’s been so declared.

In a sane world. Yes. :wink:

Hi kel.

The key word here is “normally”. See what I’ve just posted about globals above.

Hi.

That really means that a variable that isn’t declared globally in the run handler, still is a global, so whether you declare a variable global or not in the run handler makes no difference, since all variables declared in the run handler without a local scope is global per definition.

As for local variables, I think the AppleScript Language guide has an unfortunate wording in the section Kel mentions, as whence something is rest, has nothing to do if it is stored or not. It will of course always be reset when it is run, since it is never stored.

:slight_smile:

Edit

While we are talking about this subject, of storage, I find it worth mentioning, that sometimes it is feasible to avoid storing a new value in a global, due to some misheap or some other condition, then one avoids storage, by exiting the script with error number −128. In order to get values stored, you must also run it from a script runner that writes back properties. Some programs comes with their own script runners, and not all of those stores properties. Then you can save a script object from within your script with the properties, which you reload from within your main script the next time it runs.

Hello Nigel

(1) I never really understood the difference between global and property

(2) most of the time, I use properties when I wan’t to fasten the treatment of lists.
I always assumed that globals doesn’t behave the same for that.

KOENIG Yvan (VALLAURIS, France) dimanche 29 septembre 2013 12:33:19

Right. Run handler variables are global by default, but it’s as if they’ve been declared global within the run handler itself. They can only be seen elsewhere if also declared global at the top of the script (so they can be seen everywhere in the script) or in other handlers (so they can be seen in those handlers).

When using an implicit run handler, it’s not immediately clear that property and global declarations are “top of the script” and not part of the run handler.

Properties and globals (including run handler variables) are permanent features of the script and their values are saved back to the script file whenever the script’s run from that file. Local variables are only temporary and cease to exist when the scope in which they’re used exits.

They do, actually. Since they belong to the script, they can be “referenced” by writing ‘my’ in front of them (or ‘of me’ after them, of course).