rb-appscript

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 typeappscript nameRuby class
typeNull:nullNilClass
typeBoolean:booleanTrueClass/FalseClass
typeInteger:integerFixnum/Bignum
typeFloat:floatFloat
typeChar *:stringString
typeStyledText *:styled_textString
typeIntlText *:international_textString
typeUnicodeText:unicode_textString
typeAEList:listArray
typeAERecord:recordHash
typeLongDateTime:dateTime
typeAlias:aliasMacTypes::Alias
typeFileURL:file_urlMacTypes::FileURL
typeFSRef:file_refMacTypes::FileURL
typeFSS *:file_specificationMacTypes::FileURL
typeObjectSpecifier:referenceAppscript::Reference
typeInsertionLoc:location_referenceAppscript::Reference
typeType:type_classSymbol
typeEnumerated:enumeratorSymbol
unit types; e.g. typeFeetunit names; e.g. :feetMacTypes::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.