Droplet Issue

I’m trying to write a script which can serve as both an applet and a droplet. That is, when files are dropped on it, it munges the files, and when double-clicked, it asks the user to choose a file.

The problem is that, when I double-click on it, it processes the same files that were dropped on it last time!

In pseudo-AppleScript, the script looks like this:

global theFiles

on open names
set theFiles to my verify(names)
run
end open

on run
if theFiles = {}, set theFiles to choose file
process theFiles
end run

on verify(theList)
set theFiles to {}
repeat in theList
if n is the right kind of file, add n to theFiles
return theFiles
end verify

If I drag ‘n’ drop files on it, it works fine; if none of the files is the right kind, then it asks me to choose one.

But, if I just double-click on it, without a word of warning it processes the files processed in the previous run. As far as I can tell, the path is saved in <~/Library/Preferences/droplet.plist>.)

Does anyone have any idea on how to get around this behaviour (other than, perhaps, deleting or changing droplet.plist each time the script runs?).

Thanks.

AppleScript: 1.9.3
Browser: Safari 312.3
Operating System: Mac OS X (10.3.9)

Any reason you couldn’t use something like this?

on run
	choose file with multiple selections allowed
	open result
end run

on open names
	repeat with thisItem in name
		if "some sort of check" then
			--process thisItem
		end if
	end repeat
end open

Otherwise, I would try to get rid of the global variable.

on run fileList
	if fileList is {} then
		choose file with multiple selections allowed
		set fileList to result
	end if
	
	--process fileList
end run

on open droppedItems
	verify(droppedItems)
	run result
end open

on verify(aList)
	set goodFiles to {}
	repeat with thisItem in aList
		--if n is the right kind of file, add n to goodFiles
	end repeat
	
	return goodFiles
end verify

Hi alexn,

Here’s an example:

on run
	set f to choose file
	open {f}
end run
--
on open f
	set verifiedFiles to MyVerify(f)
	MyProcess(verifiedFiles)
end open
--
on MyVerify(f)
	set theFiles to {}
	repeat with this_f in f
		set n to name of (info for this_f)
		if n ends with ".pdf" then
			set end of theFiles to this_f
		end if
	end repeat
	return theFiles
end MyVerify
--
on MyProcess(f)
	-- do something with the verified files
	repeat with this_f in f
		set n to name of (info for this_f)
		display dialog n
	end repeat
	return
end MyProcess

Edited: part of the script got cut, so here’s the repost.

gl,

Thanks, Bruce and kel

That’s it – a quick test shows that the solution is indeed to move the processing from the run handler to the open handler, and use the former basically just to call the latter. Now for the drudgery of moving chunks around…

(But I still don’t understand why it should be so. There must be some reason why AppleScript saves data from one session and reuses it in the next, but I just don’t see it.)

Once again, thanks.

I recall hearing that globals are retained, even though they aren’t supposed to be. (One more reason to get rid of them!)

Edit: A simple test confirms that globals are retained.

In my view, the much better implementation of a global is to use a property:

-- Instead of:
global theFiles
-- use
property theFiles:missing value
-- and then in the handlers, set theFiles to a value

Hi,

Global variables are supposed to be retained. Here’s part of the AppleScriptLanguageGuide.pdf:

Script properties are labeled containers for values that you can use in much the
same way you use variables. The value of a script property persists until you
recompile the script that contains it, and you can easily set the property’s initial
value without resetting it each time the script is run. You can accomplish the
same thing with a global variable, but it is usually more convenient to use a
property for this purpose.

I ususally use global variables when the variable needs to be initialized in the run handler. Why use a property with an initial value when you don’t need to?

gl,

Also from the AppleScript Language Guide.

Scope of Properties and Variables Declared at the Top Level of a Script

Colour me confused.

I had thought that:

local var: known only to a script object
global var: known to every component of a script
property: ~global var, but value is retained from one session to the next

If global vars are also retained, then what’s the difference between a global variable and a property, and why should one be favoured over the other?

Thanks.

Hi alexn,

The initial value of a property is set a compile time while the value of global variables are set at run time. If you need the value to be current at run time, then use the global variable because it doesn’t need an initial value at compile time.

Global variables are commonly used with idle handlers where you want to set its initial value at run time. Some things you might set it to are dates, time, processes, contents of folders, etc. You could still use properties, but the initial value is not needed.

gl,