When writing AppleScript in Automator, what is the significance of "input" and "parameters"?
When one adds a "Run AppleScript" action to a file in Automator.app (e.g., a workflow, application, or service), the following default code is presented:
on run {input, parameters}
(* Your script goes here *)
return input
end run
What is the significance of input
and parameters
? That is to say,
Where does the AppleScript code get these variables from?
To where exactly does the AppleScript
return
theinput
to?How might these variables be ideally employed in an AppleScript application/service? Examples are appreciated.
Solution 1:
I'll try to answer my own question, making use of the relevant documentation1 provided by @user3439894 in a comment on my question.
Where does the AppleScript code get these variables from?
input
:
The
input
parameter contains (in most instances) the output of the previous action in the workflow.
The data type of input
is list
.
To display the contents of input
in Automator's corresponding "Results" pane for that specific action, simply use:
return input
parameters
:
The
parameters
parameter contains the settings made in the action’s user interface.
The data type of parameters
is reco
(i.e., a record
object).
Here is an overview of the reco
type2:
This type is used as the type of the
properties
property for theitem
class, and the type of thewith properties
parameters of theduplicate
andmake
commands.
To display the contents of parameters
in Automator's corresponding "Results" pane for that specific action, simply use:
return parameters
What, specifically, does parameters
contain?
I was curious what exactly is meant by, "settings made in the action’s user interface," so I took a look at the contents of parameters
. I learned that, unlike input
, parameters
only contains information about that specific action, not any information regarding the preceding action.
By using the following line of code,
display dialog length of parameters
I also discovered that the number of properties in parameters
for a "Run AppleScript" action in Automator is three.
They are:
|temporary items path|:
where |temporary items path|
is followed by the file path of the temporary folder created to store temporary data that may be created by the currently running "Run AppleScript" action. This folder is necessarily created upon run, even if the code does not create any temporary data. After the "Run AppleScript" action has completed, this folder and its parent folder are immediately deleted.
-
Note that
|temporary items path|
differs from(path to temporary items)
.-
return POSIX path of (path to temporary items)
produces:"/private/var/folders/p9/q_5_fbld7qzdmz6htfqjcxhw0000gn/T/TemporaryItems/"
-
return |temporary items path| of parameters
produces:"/var/folders/p9/q_5_fbld7qzdmz6htfqjcxhw0000gn/T/1BD6446F-5501-42E5-A002-29588DFF8BD8/1/com.apple.Automator.RunScript"
While both folders reside within the "T" folder, the difference between these two folders is that the
|temporary items path|
folder, as well as its parent folder, are deleted upon completion of the "Run AppleScript" action (i.e., this folder is action-specific), while thepath to temporary items
folder is never deleted and can be viewed even when the AppleScript is not running.
-
ignoresInput:
where ignoresInput
is either true or false, depending on whether the "Ignore this action's input" box found in the Options tab beneath that action in Automator is either ticked or unchecked.
source:
where source
contains the unabridged AppleScript code of that "Run AppleScript" action.
How does one read the contents of parameters
within an AppleScript?
Since the type of parameters
is not list
, one cannot simply:
set firstParameter to item 1 of parameters
as this will produce an error. But, you can convert parameters
to a list
object:
set parametersInListFormat to (parameters as list)
Then, you'll be able to execute something like this:
set individualItemFrom_parametersInListFormat to ""
repeat with individualItemFrom_parametersInListFormat in parametersInListFormat
display dialog individualItemFrom_parametersInListFormat
end repeat
Alternatively, you can skip the conversion to a list
and read the contents of parameters
simply like so1:
set item1 to |temporary items path| of parameters
set item2 to |ignoresInput| of parameters
set item3 to source of parameters
To where exactly does the AppleScript return
the input
to?
The input
of the current action is sent to the next action as that action's input
.
More info on the return
statement3:
A
return
statement exits a handler and optionally returns a specified value. Execution continues at the place in the script where the handler was called.If a handler does not include a
return
statement, AppleScript returns the value returned by the last statement. If the last statement doesn’t return a value, AppleScript returns nothing.When AppleScript has finished executing a handler (that is, when it executes a
return
statement or the last statement in the handler), it passes control to the place in the script immediately after the place where the handler was called. If a handler call is part of an expression, AppleScript uses the value returned by the handler to evaluate the expression.
How might these variables be ideally employed in an AppleScript application/service?
Now that I better understand the positional parameters of input
and parameters
, it is easier for me to imagine their practical value.
input
:
The value of input
is conspicuous and the possibilities for its implementation are immeasurable.
One very basic application would be if you want to pass a string of text that a user enters in a dialog box via an "Ask for Text" action to the next action, a "Run AppleScript" action that writes this string to file. Here is what this might look like:
parameters
:
Given that parameters
is limited to that specific action and does not contain any data from previous actions, and the data that it does contain isn't necessarily relevant, it is much less useful and flexible than input
. I can visualize the need for |temporary items path|
, but I am unable to do so for the other two properties.
Here is an example of how one might need to reference |temporary items path|
in their AppleScript:
-
Say that one wanted an Automator application to display to the user the dimensions of a web image.
The user could use
|temporary items path|
as a location to store that image, so that the code could operate on it. Then, upon completion, since the user does not need or want the image saved to disk, the AppleScript would automatically delete that image (or, more specifically, the AppleScript would automatically delete the folder that contains the folder that contains that image).-
Here is how this might be implemented:
on run {input, parameters} set theURLofImage to "https://cdn.sstatic.net/Sites/stackoverflow/company/img/logos/se/se-logo.png" set tempFolderThatIsAutomaticallyDeletedAfterRun to |temporary items path| of parameters set filename to "StackExchangeLogo.png" set fullFilepath to tempFolderThatIsAutomaticallyDeletedAfterRun & "/" & filename -- Saving image from internet to disk. -- From: http://stackoverflow.com/a/21491446/7138483 do shell script "curl -f " & theURLofImage & " -o " & fullFilepath -- Figuring out the dimensions of the saved image. -- From: https://www.macosxautomation.com/applescript/imageevents/01.html try tell application "Image Events" launch set this_image to open fullFilepath -- Extract the properties record. set the props_rec to the properties of this_image -- Purge the open image data. close this_image -- Extract the property value from the record. copy (dimensions of props_rec) to {x, y} set the image_info to "Dimensions of " & filename & ": " & "" & x & " x " & y end tell display dialog image_info on error error_message display dialog error_message end try return input end run
Also, one might want to monitor the size of the
|temporary items path|
folder, to impose a limitation, so that if its size surpasses a certain value, an error is presented to the user.
In terms of how |ignoresInput|
might be used, one could change the |ignoresInput|
setting mid-code, with the following line:
set |ignoresInput| of parameters to true
One might want to arrange their code so that if the input
meets or does not meet some condition, then the input
should be ignored. For example:
if item 1 of input > 10 then
set |ignoresInput| of parameters to true
end if
But, even if one did want to make sure that the input
was only utilized if its contents met some condition, one could accomplish this same effect without having to read or alter the |ignoresInput|
value; instead, one could simply declare their own boolean value for this purpose. So, I still think that the applicability of the |ignoresInput|
parameter
is questionable.
Similarly, I can't think of any particularly compelling reasons why one would need to read or modify the source
parameter
of their AppleScript while it runs.
What else?
One area of confusion for me still exists.
I still don't understand why Apple, in its documentation, advises against not returning anything in an AppleScript1:
The template code finally returns
input
as its output; your action should always return something as output, even if it what [sic] is given it as input.
What's the harm of removing the return
statement from one's AppleScript, if one does not need it?
If someone familiar with AppleScript methodology can address this matter for me, please drop a comment.
It is possible that I am misinterpreting the sentence.
I am interpreting this sentence to mean:
"When writing your code, you should always make sure to include a return
statement somewhere in your code."
But, the sentence could potentially mean instead:
"If you put a return
statement in your code, that return
statement is designed to always return something. If you don't assign anything to input
, then the code will simply return the same input that it received."
The ambiguity revolves around the original intent of the word, should, and whether the should is meant to act as a recommendation for the user writing an AppleScript, or whether, by should, they meant will.
Sources for passages included in this answer:
1.Automator Programming Guide - The Structure of the on run Command Handler
2.Cocoa Scripting Guide - Built-in Support for Basic AppleScript Types
3.AppleScript Language Guide - Handler Reference