6. Classes and Enumerated Types
Appscript keywords
For your convenience, appscript represents Apple event type names and application-specific class and enumerator names as Ruby symbols. Examples:
# AEM-defined data types:
:boolean
:unicode_text
:list
# Application-defined class names:
:document
:window
:disk
# Application-defined enumerators:
:yes
:no
:ask
Occasionally an application dictionary defines a type or enumerator without providing it with a corresponding name name. In these cases, the value will be represented as a raw AEM::AEType
or AEM::AEEnum
object instead of a symbol, e.g.:
AEM::AEType.new('abcd')
AEM::AEEnum.new('xyz ')
See the aem manual for more information on these lower-level objects, should you need to use them.
Common AE types
AE type | appscript name | Ruby class |
---|---|---|
typeNull | :null | NilClass |
typeBoolean | :boolean | TrueClass/FalseClass |
typeInteger | :integer | Fixnum/Bignum |
typeFloat | :float | Float |
typeChar * | :string | String |
typeStyledText * | :styled_text | String |
typeIntlText * | :international_text | String |
typeUnicodeText | :unicode_text | String |
typeAEList | :list | Array |
typeAERecord | :record | Hash |
typeLongDateTime | :date | Time |
typeAlias | :alias | MacTypes::Alias |
typeFileURL | :file_url | MacTypes::FileURL |
typeFSRef | :file_ref | MacTypes::FileURL |
typeFSS * | :file_specification | MacTypes::FileURL |
typeObjectSpecifier | :reference | Appscript::Reference |
typeInsertionLoc | :location_reference | Appscript::Reference |
typeType | :type_class | Symbol |
typeEnumerated | :enumerator | Symbol |
unit types; e.g. typeFeet | unit names; e.g. :feet | MacTypes::Units |
(Note that types marked with '*' are officially deprecated and/or their use discouraged in Mac OS X. They remain supported to ensure backwards compatibility with older applications that may use them.)
Type mapping notes
While AEM-Ruby type conversions generally work quite seamlessly, it is sometimes useful to know some of the details involved, particularly when troubleshooting code that deals with older or buggy applications.
Numbers
When packing a Bignum
, appscript will pack it either as a 32-bit integer (most preferred), 64-bit integer, or 64-bit float (least preferred), depending on the value's size.
Strings (Ruby 1.8)
Because Ruby 1.8 lacks native Unicode support, appscript unpacks all text-related AE types (typeChar
, typeUnicodeText
, etc.) as String instances containing UTF8-encoded data.
Appscript packs String instances containing UTF8-encoded data as the typeUnicodeText
AE type. If the string does not contain valid UTF-8 data, a TypeError will be raised.
You can enable a degree of UTF-8 support in Ruby's String
class via the Jcode module (included in Ruby's standard library). To use Jcode, add the following lines to the start of your Ruby scripts, irb sessions, etc.:
require "jcode"
$KCODE = "UTF8"
This will improve the display of non-ASCII characters in irb, amongst other things.
Note that while typeUnicodeText
is formally deprecated in Mac OS X 10.4+ in favour of typeUTF8Text
and typeUTF16ExternalRepresentation
, it is still in common usage so appscript continues to use it to ensure the broadest compatibility with existing scriptable applications.
Strings (Ruby 1.9+)
Each String instance in Ruby 1.9+ contains an Encoding
instance that identifies the character set used. By default, appscript unpacks a text descriptors as a String instance containing UTF-8 encoded data and a UTF-8 Encoding, and encodes a string as UTF-8 prior to packing its data into a text descriptor. To disable this behavior for individual Application
instances:
some_app = Appscript.app('SomeApp')
some_app.AS_app_data.use_ascii_8bit
# Send commands here...
Once invoked, Strings will be treated as UTF-8 encoded data with ASCII-8BIT Encoding; this is equivalent to the Ruby 1.8 behavior.
Dates and Times
Appscript packs Ruby Time
, Date
and DateTime
instances as typeLongDateTime
descriptors. (Note that AE dates does not include locale information.)
By default, typeLongDateTime
descriptors are unpacked as Ruby Time
instances. This is sufficient for most purposes; however, where the AEDesc contains a date value below or above the range supported by Ruby's Time
class, an error will occur. To unpack dates as DateTime
instances for individual Application
instances:
some_app = Appscript.app('SomeApp')
some_app.AS_app_data.use_datetime
# Send commands here...
Filesystem references
The typeAlias
AE type represents a filesystem object, and will continue to point to that object even if it's renamed or moved to another location on the same disk. The typeFSRef
and typeFileURL
types represent a filesystem location. Both can represent existing locations; the typeFileURL
type can also be used to specify locations that don't already exist.
FSSpecs are also supported for sake of backwards-compatibility with older Carbon applications that sometimes still use them. They're deprecated in OS X, however, due to lack of proper Unicode and long filename support, and their use is discouraged.
Note that appscript unpacks FSRefs, FileURLs and FSSpecs as MacTypes::FileURL
objects; users do not normally need to worry about this. MacTypes::FileURL
objects created in Ruby will always pack as type :FileURL
, however. See the mactypes manual for more information on MacTypes::Alias
and MacTypes::FileURL
.
When asking an application to coerce a return value into a file type you must specify the exact type (:alias
, :file_url
, :file_ref
, or :file_specification
) in the get
command. e.g. To get a MacTypes::FileURL
object for the current user's home folder, you would usually use:
app('Finder').home.get(:result_type=>:file_url)
Also be aware that some applications may not support coercions to all AE file types; you'll need to experiment to find out which coercions are supported.
Records
The typeAERecord
AE type is a struct-like data structure containing zero or more properties. Appscript represents AE records as Ruby hashes. The keys in this hash are usually symbols representing appscript-style property names, although they may also be AEM::AEType
values or strings.
If a hash contains a :class_
(or AEM::AEType.new('pcls')
) key, appscript will pack the remaining items into an AE record, then coerce it to the type specified by this 'class' property. Similarly, when unpacking an record-like AEDesc with a custom type code, appscript will unpack it as a hash with the type represented by a :class_
entry.
Types and enumerators
The typeType
and typeEnumerated
AE types are unpacked as Ruby symbols when the corresponding terminology is available, otherwise they are unpacked as AEM::AEType
and AEM::AEEnum
respectively.
Unit types
Unit type values are represented by instances of the MacTypes::Units
class, e.g. MacTypes::Units.inches(3.0)
. See the mactypes manual for more information.
Miscellaneous types
The Apple Event Manager defines many other AE types whose names and codes are defined by appscript for completeness. A few of these types are of occasional interest to users, the rest can simply be ignored. In most cases, values of these types will be represented by raw AE::AEDesc
instances as appscript doesn't automatically convert them to native objects.