Script Libraries

If you are running into a situation where you seem to be coding the same routines over and over again, you can create a script file with reusable handlers, called script libraries.

Script Library files can technically be located anywhere, but it is strongly advisable to put them in their expected location: ~/Library/Script Libraries. If they are in this location, they can easily be called by name, not requiring the full path to be provided.

A script library contains handlers (the same as functions) that can be called from an external script.

Here is a simple example with a parameterized handler:

Now here is a simple script that calls the script library, setting it to a variable for ease of use.
Note how the handler can be called in the standard “handler of script” or the possessive form, “script’s handler”.

And the results…


And yes, a script library can easily contain multiple handlers.

5 Likes

When you’re doing

on sayHi(name)

does “name” morph into whatever data type it’s called with? In this case, we’re obviously passing in a text value. But let’s say we made that a little more complex and said something like:

on sayHi(name,date)

and passed in “Fred Flintstone” and a date from DEVONthink, would “name” and “date” behave within the function as the “text” and “date” types that were passed in?

It seems that in many situations, AppleScript does what seems “right”. Like

"2" ^ 0.5
" 2" ^ 0.5
{2} ^ 0.5

all result in the square root of 2. In the last case, you actually get a number not a list with a single number as its element. So there seems to be some implicit casting going on. You can also freely assign to a variable like so

set a to "1"
set a to 2
set a to { a: 1, b: 2}

where every assignment overwrites the previous one. Not exactly “strongly-typed”, I’d say :wink:

Yes.

You can check the class inside a handler (and everywhere else) like this

on tid(theVariable, theDelimiter)
	set d to AppleScript's text item delimiters
	set AppleScript's text item delimiters to theDelimiter
	if class of theVariable = text then
		set transformedVariable to text items of theVariable
	else if class of theVariable = list then
		set transformedVariable to theVariable as text
	end if
	set AppleScript's text item delimiters to d -- always set them back
	return transformedVariable
end tid

And you can convert an object, like this

set theDate to current date
set theDate_string to theDate as string

But you can’t convert to every class.

You’ll find what’s possible here AppleScript Fundamentals - Coercion (Object Conversion)

That’s correct and very nice, I think :slight_smile:

If you provide a command parameter or operand of the wrong class, AppleScript automatically coerces the operand or parameter to the expected class, if possible. If the conversion can’t be performed, AppleScript reports an error.
AppleScript Fundamentals - Coercion (Object Conversion)

Generally speaking you should pass the correct data types or coerce them in the handler.

Though the language may have some ability to dynamically coerce things, I would suggest it’s a better practice to be explicit and avoid potential errors.