Conversion of Values
SenseTalk is a typeless language. That is, all values can be treated as text, and you never need to declare that a given variable will hold a particular type of value, such as numbers or dates or text, or lists of values. Internally, however, SenseTalk can hold values in different forms, converting from one representation to another as needed.
Understanding how and when these conversions occur, and the global properties that control the formatting, will let you take control of this process when necessary.
Automatic Conversion
SenseTalk converts values automatically to an appropriate internal representation as needed. When performing an arithmetic operation such as addition, for instance, the two values being added will be evaluated as numbers. The resulting value will be kept internally in numeric form until it is needed as text.
In most situations, SenseTalk's automatic value conversion will do what you want and provide the desired result. Occasionally, though, there can be surprises, so it's helpful to understand when these conversions take place and how you can control them. Consider the following example:
put ((1 + 2) & 4) + 5
When this statement is executed, SenseTalk first adds the numbers 1 and 2, getting the value 3, which is temporarily stored as a number. The next operation that is performed is to concatenate this value with 4. This is a text operation, so both values are converted to their text representation before being joined into a single text string. Finally, this result is converted back to a number so that it can be added to the number 5.
The final result displayed will be 39. Or will it? It turns out that the actual outcome may be 39, or 309, or 3009 or some other number, or it may result in an error, depending on the setting of the numberFormat
property when this statement is executed. Let's see how this can happen.
Consider that the numberFormat
property controls how a numeric value is formatted when it is converted to a text representation, including such things as the number of decimal places to show, and whether leading zeros should be displayed. In our example, the numbers 3 and 4 were converted to text form to concatenate them. The default setting of the numberFormat
property converts them to the text strings "3" and "4", resulting in the concatenated text "34". Using a number format that includes leading zeros (setting it to "00", for example) causes the numbers 3 and 4 to be represented in text form as "03" and "04", which concatenate as "0304". In order to add 5 to this string, it is converted to a number (304) giving the final result of 309.
Similar conversions happen when values stored internally as date or time values, or entire lists or property lists of values, are needed in a text format.
Binary Data Conversion
Data can be read from a file in a binary format containing the "raw" bytes of data by specifying as data
when accessing the file:
put file "/tmp/aFile" as data into dataBytes
Some operations, such as extracting a range of bytes from the data, will use the data in its raw format:
put bytes 1 to 4 of dataBytes into firstBytes
Other operations, such as displaying its value, will automatically convert the data to text. When converting between binary data and text, the defaultStringEncoding
is used to interpret the data as characters, or (in the other direction) to encode characters of text as data.
Explicit Conversions
Properties such as the numberFormat
let you control the form a value will take when it is converted to text, but don't let you control when that will occur. Look at this brief script:
set amount1 to 33
set amount2 to 44
set the numberFormat to "0.00"
put amount1 + amount2 into total
displayOutput total -- the numberFormat doesn't get applied here
displayOutput total as text -- getting total as text forces the numberFormat to be applied here
to displayOutput of something
put "The value is: " & something
end displayOutput
If the intent is to pass total
to the displayOutput
command formatted with two decimal places, the first call to displayOutput
above will fail. The problem is that total
is represented internally as a number and will be passed to displayOutput
in that form, where the displayOutput
handler's numberFormat
will determine how it ultimately gets formatted. To force these numbers to be converted to text using the local numberFormat
setting, the as text
operator can be used, as in the second call to displayOutput
above.
Similarly, the as number
, as date
, as time
, as data
, or as color
operators, or the related asText
, asNumber
, asDate
, asTime
, asData
, and asColor
functions, can be used to force a value to be evaluated explicitly in those formats.
Related Global Properties
- The NumberFormat
- The ListFormat
- The PropertyListFormat
- The DefaultQuoteFormat
- The TimeFormat
- The UnitFormats
NumberWords
, OrdinalWords
, TimeInterval
, TimeIntervalWords
, ByteSize
, and ByteSizeWords
Functions
Behavior: These functions convert a number, an interval of time (in seconds), or a file size (in bytes) to a friendlier format using words. The text that results from any of these functions (except ordinalWords) can be converted back to a number using the value()
function (below).
Example:
put numberWords(90) --> "ninety"
Example:
put numberWords(427.8) --> "four hundred twenty-seven point eight"
Example:
put ordinalWords(90) --> "ninetieth"
Example:
put timeInterval(90) --> "1 minute 30 seconds"
Example:
put timeIntervalWords(90) --> "one minute thirty seconds"
Example:
put timeIntervalWords(11520) --> "three hours twelve minutes"
Example:
put byteSize(5242880) --> "5 megabytes"
Example:
put byteSizeWords(90) --> "ninety bytes"
Other Value Conversions
In addition to numbers, lists, and property lists, there are some other values that may have non-textual internal representations. These internal values will be converted to text automatically as needed. In addition to the value types discussed earlier in this section, these include values representing dates and times, and also color values. There are also some formatting functions not mentioned earlier that can be used to convert values explicitly from one format to another.
Color values can be represented internally in a binary format. When displayed or converted to text, the current setting of the colorFormat
global property is used to control the format. Colors are described in detail in Color Values in SenseTalk.
Date and time values in SenseTalk are often represented using an internal format that includes both the actual date/time value and a text format that is used to convert the value to text when needed. To convert a date/time value from one format to another, the formattedTime
function or the convert
command can be used, along with the settings in the timeFormat
global property. Dates and times are described in detail in Date and Time Values in SenseTalk.
The merge()
and format()
functions, described in Text and Data Manipulation, are very versatile functions that can be used for a variety of general formatting needs. The standardFormat
function described in that section is useful for converting any value to a text format suitable for archiving.
The JSONFormat
and JSONValue
functions can be used to convert text data between JSON and SenseTalk.
The XMLRPCFormat
and XMLRPCValue
functions can be used to convert text data between XML-RPC and SenseTalk.