Scripting Libraries

I’ve never used a scripting library and thought I should learn a bit about this topic. So, I wrote a simple script library, which I placed in the “Script Libraries” subfolder of my home folder. It generally worked as expected, but I encountered one oddity.

The following works:

use script "File Utilities"
use scripting additions
tell script "File Utilities"
	set theFiles to getFilesByExtension("/Users/Robert/Records/", "pdf")
end tell

The following also works:

use scripting additions
tell script "File Utilities"
	set theFiles to getFilesByExtension("/Users/Robert/Records/", "pdf")
end tell

But the following fails with the error message “«script» doesn’t understand the “getFilesByExtension” message.”

use script "File Utilities"
use scripting additions
set theFiles to getFilesByExtension("/Users/Robert/Records/", "pdf")

I found a useful thread on this topic, which partially answers my question, but I wondered how you guys handled this. My scripting libraries will be used by me only and only for simple purposes. Thanks.

https://stackoverflow.com/questions/30048844/use-statement-not-working-in-applescript

I used this following AppleScript code as my “File Utilities” Library Script… as “File_Utilities_Library.scpt” in the “Script Libraries” subfolder of my home folder.

to getFilesByExtension(posixPathOfFolder, nameExtension)
	tell application "System Events"
		set theFiles to files of folder posixPathOfFolder whose name extension is nameExtension
	end tell
	return theFiles
end getFilesByExtension

I used this following AppleScript code in separate .scpt file to call on the commands from my “File Utilities” Library Script.

use fileUtilities : script "File_Utilities_Library"

set theFiles to fileUtilities's getFilesByExtension("/Users/Robert/Records/", "pdf")

The above is what I would have done using your technique.

However, in my opinion, there is one major flaw with this technique… If you make any changes and recompile and save your “File Utilities” Library Script, you’ll need to go back to every script file that uses your “File Utilities” Library and recompile and re-save them as well.

However, this following AppleScript code (though a bit more complex and longer), will load the latest version of you Library file on every run. Personally this is the route I take with all my scripts that utilize my Library files.

property fileUtilities : missing value
property theLibrary : missing value

loadLibraries()

set theFiles to fileUtilities's getFilesByExtension("/Users/Robert/Records/", "pdf")

on loadLibraries()
	set theLibrary to (path to home folder as text) & "Library:Script Libraries:File_Utilities_Library.scpt"
	set fileUtilities to load script alias theLibrary
end loadLibraries

OR this will also load the latest version of your Library file on every run.

set fileUtilities to load script alias ((path to home folder as text) & "Library:Script Libraries:File_Utilities_Library.scpt")

set theFiles to fileUtilities's getFilesByExtension("/Users/Robert/Records/", "pdf")

That’s not correct – the library will be loaded anew each time it is run. The exception is scripts run by some applications, where they are loaded the first time they are called, and not cleared until the app quits.

In further testing, I saved the script and ran it from the script menu. Indeed you are correct “the library will be loaded anew each time it is run.” However, running the script in Debugger, it needed to be re-compiled and re-run every time the library file was edited and saved… for the changes in the library file to updated in the script calling on the library.

Thanks wch1zpink and Shane for the very-informative responses. I was lost before but I understand better now.

After starting this thread, it occurred to me that Shane might touch on this issue in his ASObjC book, and he does. The following are noncontiguous snippets from page 11:

So, it would seem that for my use scenario, I have two options, and I can decide which to use based on the calling script. Very nice. :slight_smile:

That’s right. Script Debugger creates a new component instance of AppleScript each time you compile a script, but not each time you run it (otherwise it would need to be recompiled each time).

Fredrik71. Thanks for responding to my post. Your suggestion didn’t work initially but did with a slight modification:

set theFiles to (script "File Utilities")'s getFilesWithExtension("/Users/Robert/Records/", "pdf")
-- OR -- 
set theFiles to getFilesWithExtension("/Users/Robert/Records/", "pdf") of script "File Utilities"

FWIW, I encountered this same issue when using FastScripts 2 to run a script that calls a script library. Fortunately, this is a seldom encountered issue and is easily fixed by restarting FastScripts.

Yes, FastScripts 2 cached each script it ran, unlike FastScripts 3, and ran them all in the same component instance of AppleScript.