11.8. Properties and Elements
The purpose of the chain of ofs and tells is to navigate a structure formed by objects standing in a relationship of owner and attribute to one another. For example, the phrase folder 1 of application "Finder" is needed because folder 1 is an attribute of the Finder, and because I can refer directly to the Finder but not to its attributes. Figuring out how to form a chain of ofs and tells that will let you refer successfully to a desired object constitutes much of the effort of AppleScript programming, as Appendix A vividly illustrates. An application's dictionary is supposed to help you with this, though it often falls short (Chapter 20). AppleScript's own dictionary is not typically visible, so later in the book I'll list the attributes of the built-in datatypes (Chapter 13).
An attribute is either a property or an element . (In fact, I had to coin the term "attribute" because the official AppleScript documentation lacks any comprehensive term for "property or element.") A property is an attribute that this class of object has exactly one of. An element is an attribute that this class of object may have any number of, and in order to refer to one (or more), you have to say which one(s) you mean.
For example, given a list, length is a property; every list has a length, and that's the end of that. But item is an element; a list might not have any items, and if it does have some, it can have any number of them. To speak of an item or items we have to say which one(s) we mean, as in item 1. Similarly, with regard to a folder in the Finder, name is a property but file is an element.
Some properties are read-only : you can get but not set their value. For example:
tell application "Finder" get startup disk set startup disk to disk "gromit" -- error: Finder got an error: Can't set startup disk to disk "gromit" end tell
Elements in general are read-only in the sense that you can't say "set folder 1 to" something. However, you can set an element's properties (except those that are read-only, of course), and applications usually implement verbs that permit to you create and manipulate elements.
When you get an attribute's value, that value will be of some particular class. If this is one of AppleScript's built-in datatypes, what you get will usually be a copy. So, for example:
tell application "Finder" set s to name of disk 1 set s to "yoho" end tell
That code has no effect upon the name of the disk. A string came back and was stored in the variable s, and you then set the variable s to some other value, throwing away the string the Finder gave you.
But when the class of the returned value is an object type defined by and belonging to the application you're targeting, the value will usually be a reference to that object. Such a reference is a complete target. You can send a message to it, and you can get an attribute of it. You are not in control of what this reference looks like, and the way it looks may surprise you, but you shouldn't worry about that; it's a valid reference and a complete target, and that's all you should care about. For example:
tell application "Finder" set d to disk of folder 1 end tell d -- startup disk of application "Finder"
What I may have expected to see as a result of asking for this property doesn't matter; I must have faith that the Finder has given me a reference to what I asked for. To justify this faith, I can proceed to target this reference:
tell application "Finder" set d to disk of folder 1 end tell get name of d -- "feathers"
As d is a complete reference to a Finder object, I can target it; in the last line, the get message is sent to the Finder, and the name of the disk comes back. (The term name is understandable outside of a tell block targeting the Finder because it is defined within AppleScript itself; see Chapter 20.)
We have already, in several examples, taken advantage of this ability to obtain a reference and operate on it. References will be fully discussed in Chapter 12. But for now I must warn you: a reference is not a copy! So what you do to it will truly be done in the real world. For example:
tell application "Finder" set d to disk of folder 1 end tell set name of d to "yoho" -- Don't say this unless you mean it!
That code really will change the name of your hard disk, even though you're not explicitly targeting the Finder.