I’ve got a medium-sized AppleScript Studio app with functionality segmented into several scripts to keep things managable. For the sake of examples, I’ll call them Printers.applescript and Users.applescript. Each handles an awake from nib and sets several properties accordingly.
I’m hitting a roadblock trying to call methods inside these subscripts. I want to keep this code segmented, but be able to click a “Run” button and execute methods in both scripts. I don’t believe “load script” will work, since I imagine it will load new instances of these scripts. What’s the best way to execute a method in an already loaded script?
An acceptable compromise would be a “Run Printers” button whose clicked action is tied to Printers.applescript, if that “Run Printers” button can have a clicked event simulated by the top-level “Run” button. Just thinking out loud here…
If the related script is already loaded-in-memory, you can use its methods as-they-are:
Loaded script:
property x : "hello"
to sayAnything(x)
display dialog x
end
Caller script (the one which has attached a “clicked” handler):
property myLoadedScript : missing value
on awake from nib theobject
set myLoadedScript to (load script x)
--> load script dinamically at launch time,
--> where x is a valid file specification
end
on clicked thebutton --> when user wishes
display dialog "truck!" --> do my own things
set x of myLoadedScript to "bye" --> update a property from loaded script
myLoadedScript's sayAnything("groovy!") --> use a handler from loaded script
end
That won’t work, though. The application itself is loading the script. My code isn’t involved, which is the problem.
Here’s a (hopefully clearer) scenario:
Button A is tied to Parent.applescript; Button B and Popup Button C are handled by Child.applescript. Button B does two actions: adds an item to the end of the property theList, and adds an item to Popup Button C’s menu. Click click click, the menu and the list are full of items.
Button A needs to tell Child.applescript to do something, say, output theList. It loads the script, outputs the list, and gets an empty list back since it has loaded a new script into memory. I’d like a better way to tie these scripts together than by calling UI elements. (I’m resorting to hidden items in the menu bar at the moment.)
I understand now. You need accessing the properties (created on-the-fly) of script A from script B. Then… There is no way. Use your method or use an external source for all your scripts, where all them can retrieve and update shared properties. You can use a standard preferences file to keep your stuff (here some sample code: http://macscripter.net/exchange/comments.php?id=188_0_1_0_C) or any file you choose (eg, a text file in the temporary items folder).
What you are better off doing is to create a single script for all of the interface elements and child scripts for routines that can be called from the parent interface script. On the initial launch, you can then load the child scripts into the parent script and have full access to the properties and methods throughout the app. This allows you to have both the more manageable script objects and full interaction between the scripts.
I’ve found a way to references properties and functions inside already-running scripts, as I asked for in my original post. If a text field is connected to an .applescript, it has a script property set. You can tell this script to do something, or even settheExternalScriptto script of text field “inputMyField”. This still requires an intermediary UI element, but it’s a little cleaner and allows for passing of variables since you’re calling the functions themselves.
I wish I could do this with one parent script, but the size of the app and the time I have to work on this don’t warrant the effort right now. Thanks to all those that replied.