I figured out why my “Stay Open” application was having trouble… my launch-time-init variables are persistent between launches of the script. I thought only “property” variables were persistent… oh well. My applet is launched by dragging files to it and then stays open accepting more files as it works away on the files dragged to it (using an idle handler for the work part) so the open handler can get called multiple times. The issue as I see it is “how do I determine that the open handler is being called for the first time so I can properly initialize certain variables?” I currently solved the issue by using a property set to “true” when saved and it is checked when open handler is called, if true, initializes vars, then set to false. The applet “on quit” handler sets that var back to true. As an applications programmer used to programming in C++, this seems like a bit of a hack.
properties are the only variables that should persist. Can you post the code so we can take a look?
My applet is rather long so instead I threw together this little script to demonstrate the persistent problem.
Save this as an application and then run it. Change the text in the displayed dialog boxes. Run the applet again. Note that globals are persistent.
The bottom line question I have is how can have have an “initialization” phase in my applet if I have no way of knowing that it is being opened? (Since my applet is used by dragging files to it both when it is not open AND when it is running… throught “open” handler… there is no way that I can see to detect the launch event)
property propertyPersist : "I am a property"
set globalPersist to "Unitialized"
display dialog "globalPersist is: " & globalPersist default answer globalPersist
set globalPersist to text returned of result
display dialog "propertyPersist is: " & propertyPersist default answer propertyPersist
set propertyPersist to text returned of result
Properties and globals persist “ except in a few early versions of Tiger, which were bugged in this respect. Also top-level variables (ie. those used in the run handler), unless they’re explicitly declared local.
An alternative to your “hack” (which isn’t really too bad) might be for the applet/droplet to test when its file was last opened. If that was less than a second or two previously, the applet’s just been launched:
on open theseItems
set whenLastOpened to (date "Thursday 1 January 1970 00:00:00") + (time to GMT) + ((do shell script "perl -MFile::stat -le \"print stat(" & quoted form of POSIX path of (path to me) & ")->atime\"") as number)
if ((current date) - whenLastOpened < 2) then
display dialog "Bing" -- Initialise
display dialog "Bong" -- Don't.
The PERL script in the above was gleaned from eavesdropping on a recent conversation between Mark J. Reed and Takaaki Naganoya on the AS-Users mailing list.
thanks for that tip! Forgive me for being candid, but that does seem to be an even bigger hack!
Well. This is AppleScript, after all.
Yep, and I’m still figuring out the quirks. My applet is interesting in that it is essentially a wrapper for “curl” for ftp uploading… so while it is uploading files using curl in an open Terminal window, you can drag more files to it. The Terminal window is polled in the “on idle” handler and when it is not busy more commands are passed. Essentially it is a sort-of-asynchronous Terminal command handler for AppleScript.
Would something like this work for you Roland? The issue here being the app has to be ran once by double clikcing it or you could auto luanch it on login or using a cron job.
set _global to "Uninitialized"
on open _dropped
tell application "Finder" to set _global to name of item 1 of _dropped
display dialog _global
thanks, but no, merely launching it just brings up a dialog box explaining what the applet is for and should not be required to use it! I believe the “hack” that I came up with and others mentioned as well is the simplest. Use the persistency to my advantage!
Using a flag is not a hack. Sending an open event to your script app is an interrupt and creates a new process.
As a C++ programmer I consider the persistency of all global variables a quirk… having to resort to flags for what should be a process launch ‘setup’ is just downright weird.
I don’t think it creates a new process… that would be multithreading. My open handler exits after adding commands to a queue that is used in the idle handler… which also exits whether or not it does anything meaningful. This is how most “real” applications work. The only reason I coded this particular AS this way is so that it could take multiple drags of files.
Think I know what you want now. Needed some sleep. I need to go out again, but will work on it when I get back.