Sharing variable constants

I have set of script applications which together define an overall application. In other words, there is one main application which interacts with the user and spawns off several sub-applications (stay-open) which essentially run in the background until the main app is finished, then they are all told to quit.

I have a dozen or so constants I wish to share among the main script and all sub-scripts. In a former life, this was done for example with “header files” and #include statements. This allowed a set of variables/constants to be set in one file that could be included in all others that needed to use them. In other words, if any of these constants change, it would be more optimal to change them in one file instead of every script file.

For example:

– Shared Constants
set MainCity to “Boston”
set numCities to 10
set numRoads to 5
set numCars to 50
– end

I want to put these MainCity, numCities, etc. in one place to be shared by several scripts. Is that a “script library”? Or what?

How can this be done in AppleScript?

Maybe something like this?

-- constants.scpt
on getConstants()
	set constantsDictionary to {mainCity:"Boston", numCities:"10"}
	return constantsDictionary
end getConstants

Reading from another file:

set included to load script ("Macintosh HD:Users:kmitko:Desktop:constants.scpt" as alias)
tell included to set mainCity to (get mainCity of getConstants())
mainCity
1 Like

Nowadays you can do it with a Script Library

Save these lines as compiled script “MyConstants.scpt” in ~/Library/Script Libraries (~ represents your home folder)

property mainCity : "Boston"
property numCities : 10
property numRoads : 5
property numCars : 50

And access the values simply with

tell script "MyConstants"
	set theCity to its mainCity
	set numberOfCars to its numCars
end tell
4 Likes

StefanK’s example seemed a perfect solution. So I followed that but it fails. Compiled script library (in proper location) MyConstants says:

property ALL_Cities : 12

App says:

tell script “MyConstants”
set numCities to its ALL_Cities
end tell

When app is run, at set numCities causes:
—————
AppleScript Execution Error

Can’t make ALL_Cities into type reference.
—————

Seems straightforward and simple, but why does it fail?

Ok, I deleted “use scripting additions” from MyConstants and now the app runs through without error.

Follow up to this…

Let’s say I create Script Library “MyConstants” which has 100 properties. And I have script “MyApp” which uses “MyConstants” but only uses 10 of its properties. Does the MyApp script contain objects for all 100 properties from the library or only the 10 it uses?

And perhaps I wish to expand MyConstants to contain handlers also shared by my apps. Can I put handlers into this script library, and will the scripts that use this library contain only the handlers it uses or all the handlers in the library?

I am trying to pare down code in a large script to reduce the size of its ID table and hopefully eliminate Internal Table Overflow errors.

It depends how you invoke the MyConstants script. With a tell script “MyConstants”... block, the properties belong to the MyConstants script and aren’t inherited by MyApp. Therefore, the only values that MyApp retains outwith end tell are those ten that you’ve explicitly made copies of.

Yse.

The handlers in the script library get treated in much the same manner as the properties, so if you access a handler using a tell block, you’ll need to store it in a local variable in order for MyApp to retain its own copy to use outwith the end tell.

However, this will only work if the handler being copied doesn’t itself need to reference anything from the MyConstants script, which will include any references to its properties. You might assume that if you create a copy of one the properties and give it the same name, then any references to that identifier (property name) inside a handler that you’ve copied would simply use the value that you copied over as well. But that is not the case: the handler you copy is a compiled piece of code, and the reference to a named property will be specific to the script that originally owned the handler and cannot be changed.

So you’ll likely be limited to handlers of very basic functionality that only utilise locally-declared parameters.

To not be limited in this manner, then you would need to either import the MyConstants script into MyApp, bringing with it all properties and handlers declared within; or you define an inheritance relationship between the two scripts, e.g. by adding the following property declaration to MyApp:

property parent: script "MyConstants"

Indeed. As I said above, there are some significant limitations inherent when you’re importing compiled code, such as a handler from a script library. However, I store all of my handlers as text scripts, one-per-file. I then import a handler into other scripts on an ad-hoc basis by reading in the source code as text and compiling it within the script that wants to make use of it, which is done at run time.


I’ve seen a couple of users post some pretty lengthy descriptions of their own script library implementations, and fairly recently. So you should scroll down the list of posts of do a search to have a gander at what other methods people have divised.

CJK, thank you for this. Very informative and helpful. I had other stuff today but will reply more.

Have a read thru this.

Especially about the part of inheritance.
You can limit the number of you main global scripts in the top object

Thank you both. I feel dumb because first place I looked was the Language Guide but somehow I couldn’t find the whole bit on Script Objects and Libraries. All very helpful thank you I get it now.