Guide
Understanding Object Specifiers
RubyOSA bridges Ruby to a Mac OS X application. The objects that RubyOSA return are actually proxies that represent data on the application side. These objects act like normal Ruby objects but transparently communicate back to the Mac OS X application via Apple events.
Object Specifiers
You can think of objects returned by RubyOSA as pointing to the real application objects. These objects are called object specifiers. For example, the following object specifier points to the 41st track of your iTunes library:
OSA.app('iTunes').sources[0].playlists[0].tracks[42]
By default, RubyOSA doesn't resolve object specifiers for you. This means that no Apple event will be sent when interpreting the expression above.
RubyOSA will use the metadata from the scriptable definition to
properly type object specifiers. Sometimes you may need to get the
real type of the object. This can be done by resolving the object
specifier, and this requires an Apple event. You can do this using the
#get method:
track = OSA.app('iTunes').sources[0].playlists[0].tracks[42] track.class() # -> OSA::ITunes::Track track.get.class() # -> OSA::ITunes::FileTrack
You can also set the OSA.lazy_events global variable to
false to automatically resolve all object specifiers (see
the Changing the Global Settings section for more details).
Object Specifier Lists
You may have noticed that RubyOSA doesn't return real Array objects
but OSA::ObjectSpecifierList objects.
OSA.app('iTunes').sources # -> OSA::ObjectSpecifierList
This specific class mixes the Enumerable module so that you
can call almost all Array methods on it. RubyOSA doesn't
convert to real Array objects for performance reasons.
You can convert an OSA::ObjectSpecifierList object to a
Ruby Array by calling the #get method on it. Note that this
will automatically resolve all objects specifiers in the list as well:
OSA.app('iTunes').sources.get # -> [OSA::ITunes::Source, ...]
The classes of object specifiers can hold attributes. For example, the
OSA::ITunes::Item class has a name property. RubyOSA
provides a convenience facility to collect all of the attributes of a
given name from an object specifier list:
OSA.app('iTunes').sources.every(:name) # -> ["Library", "Radio"]
The main advantage of using #every is that only one Apple
event will be sent. The following code returns the same value but
requires two Apple events to be sent:
OSA.app('iTunes').sources.map { |s| s.name }
Using #every can make a difference when working on a large
collection of objects.
