property, shell scripts, app bundles and the AS editor

Puzzling problem; I use this line in a script to add the current date to an email that the rest of the script generates on run.

property currentdate : (do shell script "date '+%m/%d/%y'") as string 

But… if I run that script from the dropdown AS menu or double click on the app on the desktop, I get not the current date, but the date of the last run of the script.

However, if I open the script in the script editor and use the “Run” button, then the script gives the correct date.

Full script:

property currentdate : (do shell script "date '+%m/%d/%y'") as string
property mysubject : "Work for " & currentdate & ""
property Mysender : "email"
property Myrecipient : "email"
property EmailBody : "Work for " & currentdate & " "

tell application "Mail"
	set newMessage to make new outgoing message with properties {subject:mysubject, sender:Mysender, visible:true, content:EmailBody}
	tell newMessage
		make new to recipient with properties {address:Myrecipient}
	end tell
end tell

What’s a consistent way to generate the correct date? I have tried

set currentdate to do shell script "date '+%m/%d/%y'") as string

with no luck.

Hi,

the quotation and the coercion is not needed


set currentdate to do shell script "date +%m/%d/%y"

Notice that Stefan’s used ‘set’ instead of a property.

The intial values of properties are set when the script’s compiled, so you’ve been getting the date/time when that was done. The ‘set’ command, however, is executed when the script’s run, so the result will be more . er . up-to-date. :slight_smile:

The same applies, of course, with the other properties which depend on the value of ‘currentdate’.

Many people use properties when they could just as easily use ordinary variables set at run time. I don’t think it’s a particularly good practice. (My opinion.) It doesn’t make the script any easier to read or maintain and the values of the properties are saved back into the script file every time the run ends (assuming the script’s run in its own right and not as a subprocess in some other script).

Good uses for properties in a ‘"top level’" script are to store values which take a long time to work out and are never going to change; or to store values which may change and which the script will need to know about next time it’s run.

That was it: using set instead of property. I was using property as it was the way the email script I found was written. I have used set in other scripts I have written, but didn’t know the difference. Thanks.

Now, a problem with one script has come up when I changed it to using set instead of property. Using the script below, which opens a new email when an attachment is dropped on it, I get the error “The run handler is specified more than once, or there were top-level commands in addition to the run handler” when I try to save the script.

I don’t know where to start looking. Maybe it’s structural because of the change from property to set?

set currentdate to do shell script "date '+%m/%d/%y"

set Myrecipient to "emailhere"
set ccrecipient to "emailhere"

set mysubject to "Monthly Invoice "
set EmailBody to "" & currentdate & "

Hello,

Monthly Invoice attached

Thanks
"


on run
	tell application "Finder"
		set sel to (get selection)
	end tell
	new_mail(sel)
end run

on open droppedFiles
	new_mail(droppedFiles)
end open

on new_mail(theFiles)
	tell application "Mail"
		set newMessage to make new outgoing message with properties {visible:true, subject:mysubject, content:EmailBody}
		tell newMessage
			make new to recipient with properties {address:Myrecipient}
			make new cc recipient with properties {address:ccrecipient}
			
			tell content
				repeat with oneFile in theFiles
					make new attachment with properties {file name:oneFile as alias} at after the last paragraph
				end repeat
			end tell
		end tell
		activate
	end tell
end new_mail

with this syntax you have an explicit and an implicit run handler. The script won’t compile.

Put the immutable strings in properties and the mutable into the new_mail handler


property Myrecipient : "emailhere"
property ccrecipient : "emailhere"
property mysubject : "Monthly Invoice "
property myBody : "

Hello,

Monthly Invoice attached

Thanks
"


on run
	tell application "Finder"
		set sel to (get selection)
	end tell
	new_mail(sel)
end run

on open droppedFiles
	new_mail(droppedFiles)
end open

on new_mail(theFiles)
	set currentdate to do shell script "date '+%m/%d/%y"
	set EmailBody to currentdate & myBody
	tell application "Mail"
		set newMessage to make new outgoing message with properties {visible:true, subject:mysubject, content:EmailBody}
		tell newMessage
			make new to recipient with properties {address:Myrecipient}
			make new cc recipient with properties {address:ccrecipient}
			
			tell content
				repeat with oneFile in theFiles
					make new attachment with properties {file name:oneFile as alias} at after the last paragraph
				end repeat
			end tell
		end tell
		activate
	end tell
end new_mail

Or of course set them all in the new_mail handler. It’s a close call. Putting the immutable strings into properties at the top of the script makes them easier to find and edit at a later date. Setting them in the handler prevents them from being saved back into the file every time (because the variables are local) and doesn’t present mystery variables to anyone reading the handler. But in a short script like that, it doesn’t make a great deal of difference.

Thanks! Works now. Still learning this stuff. I need to learn more about the architecture of scripts when I start trying to write longer ones.