12.5. Dereferencing a ReferenceOnce you have a variable whose value is a reference, AppleScript behaves with confusing inconsistency when you try to use it. In some cases, you can't use the reference unless you explicitly dereference it; in other cases, AppleScript dereferences it for you implicitly when you use it. AppleScript can even behave both ways with one and the same reference. When AppleScript performs implicit dereferencing , the reference is completely transparent; it acts precisely as if you were saying the incantation that's frozen inside it. This is exactly the same phenomenon noted in the previous sectionyou can't learn from a reference that it is a reference, because it acts as if it were the thing referred to. tell application "Finder" set x to folder 1 end tell name of x -- Mannie class of x -- folder set name of x to "Moe" None of that ought to be possible. A reference's class isn't folder, and a reference doesn't have a name property that you can get and set. In this case, though, it happens that the reference is a reference to a thing whose class is folder and that has a name property. AppleScript dereferences the reference implicitly; it treats the reference as if it were the thing referred to. But in this example, an attempt to use the same reference transparently runs up against a brick wall: tell application "Finder" set x to a reference to name of folder 1 end tell set x to "Moe" If you were hoping that this code would set the name of the Finder's folder 1 to "Moe", you're doomed to disappointment. It didn't: you set the variable x to the string "Moe" (and you lost your reference). The reason is that the transparency of references can't be permitted to destroy your access to your own variables. Thus, when you perform an assignment , not to a property of a variable that's a reference but to the variable itself, AppleScript stops treating the reference transparently. The assignment is an ordinary assignment to a variable; what's inside the shoebox is thrown away and a new value is put into the shoebox. Similarly, the boolean equality and inequality operators do not treat references transparently by dereferencing them (see "Comparison Operators" in Chapter 15). Here's a simple example: set x to 3 set y to a reference to x x = y -- false y = 3 -- false There's no implicit dereferencing here, and 3 is not the same as a reference to x. With other operators, though, AppleScript does dereference, which makes for some paradoxical-looking results: set x to 3 set y to a reference to x x = y -- false x + 0 = y + 0 -- true x is not less than y and x is not greater than y -- true In situations where AppleScript doesn't implicitly dereference a reference for you, you can dereference it yourself. The way you do this is with the contents of operator. So, this code successfully renames a folder in the Finder: tell application "Finder" set x to a reference to name of folder 1 end tell set contents of x to "Moe" Here's another example:
set x to 10
set y to a reference to x
set contents of y to 20
x -- 20 Here's the equality example again:
set x to 3
set y to a reference to x
x = contents of y -- true The contents of operator works on any value. If the value isn't a reference, the result of applying the contents of operator is simply the value itself. In this example, the use of the contents of operator (twice) is essentially pointless; AppleScript basically just throws it away, and you end up saying the very same thing you'd say if you simply omitted the words contents of from the code:
set x to contents of "Mannie"
contents of x -- "Mannie" You can take advantage of this in dealing with the equality example. Let's say you don't know which of x and y is a reference. That's okaydereference them both, as it does no harm:
set x to 3
set y to a reference to x
contents of x = contents of y -- true However, this is not to imply that you can simply use the words "contents of" capriciously. They do mean something, after all! So, this will cause a runtime error: set x to "Mannie" set contents of x to "Moe" -- error This is like saying set "Mannie" to "Moe", which doesn't work, because "Mannie" is a literal, not the name of a variable. If a value is a reference to an object belonging to an application, the contents of operator might or might not get you a different reference. So, for example: tell application "Finder" set x to folder 1 end tell x -- folder "Mannie" of desktop of application "Finder" set x to contents of x x -- folder "Mannie" of folder "Desktop" of folder "mattneub" of folder "Users" of startup disk of application "Finder" set x to contents of x x -- folder "Mannie" of folder "Desktop" of folder "mattneub" of folder "Users" of startup disk of application "Finder" The exact behavior here is entirely up to the target application, and doesn't have any particular significance. In each case you're just telling the application to do a get whose direct object is the very same "phrase" the application handed back to you previously as a reference. Whether the application returns the same phrase or a different phrase referring to the same object is entirely its own business. |