I have a folder in my Scripts folder named library from which i call handlers. If I change the handler (saved as .scpt) and then run the script that calls the handler any change to the handler is not recognized. It is only when I change the name of the script in the library folder and that it works. Is their a cache somewhere that the scripts looks for info? I can find various caches to apps but not a script.
Are you using code like the following to load the library script?
-- Load a library script.
property scriptObj : load script ((path to scripts folder from user domain as unicode text)& "Library:doit.scpt")
on run
-- Use the library script.
scriptObj's doit()
end run
If so, the caching effect you are seeing is because property initialization is only done at compile time. In Script Editor you can explicitly ask for compilation with Script > Compile (Command-K). Or if a script has modifications since it was loaded, Script Editor will automatically compile the script when you run or save it (except for when saving as plain text).
This means that the library script (“doit.scpt”) will only be loaded once, when the script is compiled. From then on, a separate copy of the library script is save inside the main script. The library script is no longer needed and can even be deleted.
If you do not want this behavior, one variation you can use looks like the following.
property scriptObj : missing value
on run
-- Load a library script.
set scriptObj to load script ((path to scripts folder from user domain as Unicode text) & "Library:doit.scpt")
-- Use the library script.
scriptObj's doit()
set scriptObj to missing value
end run
With this variation, the library script is loaded from the library every time the main script runs. The reset at the end is just so that the main script does not have to write out its copy of the library script when it finishes (since, in many (but not all) execution contexts, a script’s properties are automatically persisted (saved at termination)).
Also, if you only need to access the library script from a single handler you could even get rid of the property and use a local variable instead.
Thanks Chrys for a most interesting and informative reply.
I was obviously under the impression that the script loads the library script at the time of execution. The idea being that a number of scripts might reference the library scripts. If a modification needs to be made to a handler then I only have to modify the library scripts saving me a lot of time. I now know why thats failing
Another thing I don’t understand is how would I action a library handler with a local variable?
I am not sure I understand “action a library handler”. Do you mean “execute a handler from a loaded (library) script”? If so, there is no difference in how you call such a handler. A property is just a special kind of variable, so the code for using properties and using local variables looks the same. The only difference is how the variable is declared.
Variables in AppleScript are usually broken down into three categories: properties, global variables, and local variables. Properties are simply pre-initialized global variables. Both properties and global variables are saved across script runs in most contexts. Properties and global variables are directly accessible in the entire script (or script object) in which they appear (unless shadowed). Access to local variables are limited to the scope of a single handler. The values of a handler’s local variables are discarded each time the handler finishes. Variables created with set or copy (those that do not have a prior property, global, or local declaration) are created as local variables.
A variable can be explicitly declared as local (local varName) and have the same name as a property or global variable. Such a local variable is said to “shadow” the property or global variable. In the handler, accesses to the variable after the local declaration will be to the local variable and not the property or global variable.
Since a property in a script is just another kind of variable, using a local variable looks the same as using a property. The code scriptObj’s doit() runs the doit() handler from script object stored in the scriptObj variable. It does not matter whether scriptObj is a local variable, global variable or property (or whether scriptObj was loaded from a file or created by an “inline” script object definition).
To make my last example use a local variable instead of a property, just take out the top-level property declaration. If you want to explicitly declare the variable as local, you can add local scriptObj somewhere before it is first used, but again, without the property (or global variable) declaration, it will automatically default to being a local variable.