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.

8 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)

1 Like

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)

1 Like

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.

pretty cool

Indeed they are another powerful extension of AppleScript back from the glorious times of Sal Soghoian :heart:

1 Like

Wasn’t he responsible for JXA and fired by Apple, too?

1 Like

He was the brilliant mind and evangelist behind most of Apple’s technologies.
He has been working with Omni Group for years on their Omni Automation stuff based on JS.
And no, he wasn’t fired as much as his position was dissolved.

I don’t know any of the people involved, but FWIW, in a 2019 Hacker News thread, the person who wrote a very useful and pretty amazing multilanguage interface to Mac scripting (appscript, not to be confused with Apps Script or AppScript) wrote about his interactions with Soghoian and Soghoian’s legacy with respect to JXA and Mac automation. It is not flattering, to put it mildly, although the author’s bitter tone and self-aggrandizing statements make a person wonder whether he may not be without some blame too.

As an aside, even though it’s officially no longer supported, I still used the Python version of appscript to write some Python utilities that interact with DEVONthink. It is very impressive and very nice to work with.

1 Like

I’ve read some of their diatribes in the meantime. The frustration is understandable, the attitude less so. And the fact remains that JXA remains unfinished business

The author indeed sounds arrogant and bitter. :confused:
And his anecdotes change nothing about how I feel or the incredible impact Sal has had on the lives of many, many people for a very long time.

2 Likes