Miscellaneous Operators
( )
(Parentheses) Operator
Behavior: Use parentheses to control the order in which operations are performed within an expression. See Precedence of Operators to understand the order in which operations are performed when parentheses are not used. When in doubt, use parentheses to ensure operations are carried out in the desired order. Also see Uses of Parentheses for more details.
Syntax:
( expression )
Example:
put 2 * (height + width) into perimeter
AsList
Function
Behavior: The asList
function is called with an object (property list) as a parameter, it first checks whether the object has an asList
property. If so, its value is returned. If not, and the object has an asListExpression
property, the value of that property is evaluated as an expression (equivalent to calling the value()
function) to obtain the list value. If the object has neither of these properties, an asList
function message is sent exclusively to the object and its helpers, and its return value is used.
If the target is not an object (or does not have an asList
or asListExpression
property or an asList
function handler) and it is not already a list, the target's string value is evaluated as an expression (equivalent to calling the value()
function) to obtain the list value.
Syntax:
{the} asList of factor
asList( expr )
Example:
put file "scores" as a list into testScores
Related:
Is A
, Is Not A
, Isn't A
, Is All
, Is Not All
, Isn't All
Operators
Behavior: Checks whether a value is valid as a particular type, or analyzes the contents of a value. You can test whether a value is or is not a number
, integer
, even number
, odd number
, positive number
, negative number
, positive integer
, negative integer
, point
, rectangle
, date
, time
, or Boolean
. A variable can be tested to see whether it is a list
, a range
, an iterator
, a file
, a folder
, a tree
, or an object
. You can also test whether a character or all characters in a value are digits
, letters
, alphanumeric
, uppercase
, lowercase
, punctuation
, blank
(or whitespace
), blankOrReturn
(or whitespaceOrReturn
), or controlChars
. You can tell if a value is actually a reference to another container, by testing whether or not it is a reference
. In addition, the is a
operator can also be used to test for custom object types if the object defines an objectType
property (see the ObjectType
property in Special Properties).
Syntax:
valueToTest is {not} a typeIdentifier
valueToTest is {not} all typeIdentifier
Examples: The following expressions all yield "true":
put pi is a number
put pi is not an integer
put -12 is an even number
put 5683 is an odd number
put 98.6 is a positive number
put 0 isn't a positive number
put -13.2 is a negative number
put 144 is a positive integer
put -1 is a negative integer
put "123, 12.5" is a point
put "123, 12.5, 245, 25" is a rectangle
put (snow is greater than rain) is a boolean
put (a,b,c) is a list
put 14..94 is a range
put (a,b,c) is an iterator
put "July 4, 1776" is a date
put "/System/Library/Fonts/Courier.dfont" is a file
put "/System" is a folder
put (partnum:"4X56N32", qty:14) is an object
put 6 is a digit
put character 2 of "4X56N32" is a letter
put "J946Ux" is an alphanumeric
put "a" is a lowercase
put "ABCdef" isn't all uppercase
put "(),.;:!?[]{}%\’/" is all punctuation
put space is a blank
put space & tab & return is all blankOrReturn
put tab is a controlChar
put @foo is a reference
put radius:23, objectType:("Shape", "Circle") is a "Circle"
put <"[", character, "]"> is a pattern
An error is raised if typeIdentifier is not one of the following valid identifiers, or an expression that evaluates to one of the built-in identifiers listed below, unless valueToTest is an object or property list.
If the valueToTest is an object, the is a
operator evaluates to the value returned by sending an isObjectType
function message to the object, with typeIdentifier as a parameter. The default implementation of this function checks the objectType
property of the object contains the typeIdentifier. If a property list has an objectType
property, it may be a single value or a list of values. If typeIdentifier is equal to any item in the objectType
list, the is a
operator will evaluate to true, otherwise it will be false.
Identifier | True When the Value to Test Is |
---|---|
Boolean logical | "true" or "false", "yes" or "no", "on" or "off", or empty |
date time | a value other than a single number that can be converted to a date or time value |
even number | a whole number that is evenly divisible by 2 |
file | a file object or file name of an existing file, not a folder |
folder directory | a file object or file name of an existing folder, not a plain file |
integer int | a "whole" number without any fractional part |
iterator | an iterable value such as a list or range |
list | a list |
negative integer | a whole number that is less than zero |
negative number | a number that is less than zero |
number | a number |
object propertyList | an object or property list |
odd number | a whole number that is not evenly divisible by 2 |
pattern | a pattern definition using SenseTalk's pattern language |
point | a list of two numbers, or two numbers separated by commas |
positive integer | a whole number that is greater than zero |
positive number | a number that is greater than zero |
range | a range |
rectangle rect | a list of four numbers, a list of two points, or four numbers separated by commas |
reference | a reference to another container |
tree | a tree |
The following identifiers can be used to test the type of characters in a text value:
Identifier | True When Every Character of the Value to Test Is |
---|---|
alphanumeric | a letter or a digit |
blankOrReturn whitespaceOrReturn | a space or a tab or a return |
blank whitespace | a space or a tab |
controlChar controlChars | a hidden control character such as return, tab, formfeed, etc. |
digit digits | a digit: 0,1,2,3,4,5,6,7,8, or 9 |
letter letters | an upper- or lower-case letter |
punctuation | a punctuation character such as , . ! ? ; : |
lowercase | a lower-case letter |
uppercase | an upper-case letter |
There Is A
, There Is Not A
, There Isn't A
, There Is No
, Exists
, Does Not Exist
, Doesn't Exist
Operators
Behavior: Tests for the existence of a file, folder, variable, object, or object property. In the case of variables, this operator returns true if the variable has been assigned a value.
Syntax:
there is [a | an] thingThatMayExist
there is not [a | an] thingThatMayExist
there isn't [a | an] thingThatMayExist
there is no thingThatMayExist
thingThatMayExist exists
thingThatMayExist does not exist
thingThatMayExist doesn't existWhere thingThatMayExist is one of:
file fileName
folder folderName
object objectIdentifier
property propertyName of _someObject
variable localOrDeclaredVariableName
global globalVariableName
universal universalVariableName
Example:
if there is a folder "BankReport" then ...
Example:
if there is no file "secretpasswords" then ...
Example:
if there is not an object "printHelper" then ...
Example:
if there is a property cost of material then ...
Example:
if there is a variable controller then ...
Example:
if file "answers" doesn't exist then create file "answers"
Example:
if property sequence of part exists then add 1 to part's sequence
Is Within
, Is Not Within
, Isn't Within
Operators
Behavior: Tests whether a point lies within a rectangle, whether one rectangle is completely contained by another, or whether a value falls within a given range. All forms of the is within
operator test for containment inclusive
of the edges or endpoints of the containing rectangle or range. So, for example 9 is within 5..9
will evaluate as true.
Points are always specified as a pair of numbers representing the x and y coordinates of the point. Usually, these two values are given as a two-item list such as [12,42], but a text string containing two numbers separated by commas can also be used, such as “12,42”.
Rectangles are specified as 4 numbers, representing the locations of the left, top, right, and bottom of the rectangle, such as [5,18,105,118] — this rectangle would actually be a square, with both width and height of 100. You can also think of the four numbers as describing two points, which are opposite corners of the rectangle. A rectangle can also be specified as a list of 2 points, such as [ [5,18], [105,118] ].
Syntax:
point is {not} within rectangle
rectangle1 is {not} within rectangle2
value is {not} within range
Example:
if mousePoint is within windowBorder then ...
Example:
if lastLoc + [12,8] is within [10,10,90,50] then ...
Example:
if windowRect is not within screenRect then ...
Example:
if day is within 1 .. lastValidDay then ...
&&&
List Concatenation Operator
Behavior: Joins two lists or values into a single list of values. The result of this operation is always a list, even if one of the operands is empty.
Syntax:
operand1 &&& operand2
Example:
put [1,2,3] &&& [4,5] into oneList -- results in [1,2,3,4,5]
Example:
put oneList &&& 6 --> [1,2,3,4,5,6]
Example:
put 0 &&& oneList --> [0,1,2,3,4,5]
Example:
put 12 &&& 42 into luckyList -- results in [12,42]
Joined By
, Split By
Operators
Behavior: The joined by
operator combines the elements of a list or property list into a text string. The split by
operator does the reverse, taking a text string and producing a list or property list from it. The word combined
may be used in place of joined
, and either with
or using
may be used instead of by
in either operator if you prefer.
When working with property lists, two separators should be used. The first indicates the text separator between elements, and the second specifies the text separator between each key and its corresponding value. To split or join a list, only a single separator is needed.
Syntax:
sourceStructure [joined | combined] [by | with | using] separator1 {and separator2}
sourceText split [by | with | using] separator1 {and separator2}
Example:
put path split by "/" into components
Example:
set newPath to components combined using "/"
Example:
put {a:1, b:2} joined with ";" and "=" --> "a=1;b=2"
Example:
split inputString by <character in ".,:;">
As
Operator
Behavior: The as
operator can be used to tell SenseTalk to treat a value as a particular type, or force conversion to a different representation at a particular point in a script. For example, the as text
operator can be used to force textual comparisons of values that might otherwise be compared as numbers.
Syntax:
sourceValue as [text | {a} string | number | date | time | color | data | {a} {property} list | {an} object | {a} tree | boolean | integer | base64]
Example:
if today is "April 15" as date then payTaxes
Example:
performTextOperation (hours * rate) as text
Example:
put "007" is equal to "7.0" --> True (numeric comparison)
Example:
put "007" is equal to "7.0" as text --> False
Example:
put file "cust2497" as a property list into customer
Internally, the as
operator calls the asText
, asNumber
, asDate
, asTime
, asColor
, asData
, asList
, asObject
, and asTree
functions.
The existence of the as
operator does not imply that SenseTalk is a "typed" language. In fact, it is an "untyped" language, with values converted automatically to whatever internal representation is needed at any time. In practice, there are only a few relatively rare situations in which you will need to use this operator to explicitly force the internal representation of a value.
For example, SenseTalk won't automatically perform a date/time comparison just because two values could be treated as date/time values. To compare two values as date/times, both values must be in that representation, otherwise they will be compared as text, giving very different results (April comes before January alphabetically, for instance). One way to ensure this is by specifying as date
or as time
after both values as needed, as shown in the first example above.
Similarly, as data
can be used to perform direct comparisons of raw binary data values rather than their text representations. It is most often used when reading or writing binary data files to keep the data in binary format. The byte
chunk type can then be used to access individual bytes or byte ranges within the data.
The as list
and as property list
(or as object
) operators are somewhat different. They don't merely indicate how a value should be treated, but for any value that isn't already in the requested representation they will evaluate that value's text as an expression (in the same manner as the value()
function) to produce the requested structure. The as tree
operator will similarly evaluate text as XML (equivalent to calling the treeFromXML()
function).
When the value to be converted is an object, it may control its representation in each format if it implements an asText
, asNumber
, etc. handler, or has special properties that apply for the requested type. See the relevant as…
function documentation for full details.
See Conversion of Values for more information on automatic conversion of values, and when you might use the as
operator.
AsObject
Function
Behavior: When the asObject
function is called with a tree as a parameter, it converts the tree to a property list representation, according to the setting of the treeFormat
's useStandardFormat
property, otherwise the parameter's string value is evaluated as an expression (equivalent to calling the value()
function) to obtain the property list value.
Syntax:
{the} asObject of factor
asObject( expr )
Example:
set ComputerSpecs to an empty tree
set ComputerSpecs's _tag to "Gaming"
set ComputerSpecs 's RAM to 16 GB
set ComputerSpecs 's Storage to 2 TB
put ComputerSpecs -- Displays the text representation of the tree '<Gaming RAM="16 gigabytes" Storage="2 terabytes"></Gaming>'
put ComputerSpecs as an object -- Displays the property list representation '{_tag:"Gaming", RAM:"16 gigabytes", Storage:"2 terabytes"}'
Related:
(If ... Then ... Else ...)
Operator
Behavior: Evaluates to one of two values depending on some condition. The (if ... then ... else ...)
operator, also known as a Selector Expression, can be used to select one of two values or an optional value within an expression, or to select one of two containers.
The selector expression, although it looks very similar, is not the same as the if ... then ... else ...
control structure which controls whether statements are executed or not. Note that parentheses are always required around a selector expression, and it must always include a then
expression. If the else
expression is omitted, empty is assumed (that is, it's the same as saying else empty
). The else
expression is required when specifying a container.
Syntax:
( if condition then expression1 {else expression2} )
Example:
put "Delivered " & count & " widget" & (if count > 1 then "s")
Example:
put (if a>b then a else b) into bigger
This is equivalent to:
if a>b then put a into bigger else put b into bigger
Example:
The selector expression can also be used anywhere a container is expected, provided that both the then
and else
expressions specify containers:
add 100 to (if a<b then a else b)-- add to whichever is smaller
This is equivalent to:
if a<b then add 100 to a else add 100 to b -- add to whichever is smaller