Confused by "Use Framework" and "Do Shell Script" Interaction ...

I don’t understand why this code compiles in Script Editor


set mark1 to my GetTick_Now()
repeat nrepeats times
	set theFileExists to FileExists(theFile)
end repeat
set mark2 to my GetTick_Now()

on FileExists(theFile) -- (String) as Boolean
	set theFileExists to (do shell script "[ -e " & quoted form of theFile & " ] && echo true || echo false") as boolean
	return theFileExists
end FileExists

on GetTick_Now()
	## From MacScripter Author "Jean.O.matiC"
	## returns duration in seconds since machine start, calculated using ticks
	script GetTick
		use framework "Foundation" --> for more precise timing calculations
		on Now()
			return (current application's NSDate's timeIntervalSinceReferenceDate) as real
		end Now
	end script
	
	return GetTick's Now()
end GetTick_Now

and this will not compile. The order of the two handlers is reversed and now Script Editor doesn’t recgonise “do shell script”


set mark1 to my GetTick_Now()
repeat nrepeats times
	set theFileExists to FileExists(theFile)
end repeat
set mark2 to my GetTick_Now()

on GetTick_Now()
	## From MacScripter Author "Jean.O.matiC"
	## returns duration in seconds since machine start, calculated using ticks
	script GetTick
		use framework "Foundation" --> for more precise timing calculations
		on Now()
			return (current application's NSDate's timeIntervalSinceReferenceDate) as real
		end Now
	end script
	
	return GetTick's Now()
end GetTick_Now

on FileExists(theFile) -- (String) as Boolean
	set theFileExists to (do shell script "[ -e " & quoted form of theFile & " ] && echo true || echo false") as boolean
	return theFileExists
end FileExists 

Commenting out the line "use framework “Foundation” " removes the compile problem, but obviously results in not runnable code.

Can anyone provide a hint why this is so?
I had thought that the Framework would be either be used for the entire parent script, or only for the entire child script, but there is some before-after dependency that I don’t understand

An obvious work around is to always put the GetTick_Now() handler at the bottom of the scrript, but I’d like to understand why.

It’s a quirk of the compiler. Once you have any use statement at the top of a script, you also need to have a use scripting additions statement to use additions (or wrap them in using terms from…).

It looks like the compiler is ignoring scripting addition terminology once it comes across the use framework statement, from that point on.

The simplest solution is to add a use scripting additions statement at the top of the script. This can also potentially have some other benefits.

You should also add a parent property to that timing handler, to avoid other potential side-effects. Like this:

        property parent : a reference to current application

You can read more here:

https://latenightsw.com/adding-applescriptobjc-to-existing-scripts/

No, it actually returns the duration since January 1, 2001 00:00:00 UTC.

Edited to fix reference date.

Shane, thank you for a very useful reply and app note.

Unexpectedly, the reference time for this measurement seems to be the beginning of 2000 GMT.

At about 21:19 EST I get a value of “553569539.430717” for GetTick_Now() which is about 17.54 years.

Sigh that’s sort of what I meant to say above. Unix’s reference date is in 1970, but Cocoa’s reference date is January 1, 2001 00:00:00 UTC. I’ll edit it accordingly.

(The difference between the two reference dates is 978307200.0, as defined in the NSDate.h file.)