Does anyone know why this applescript works? I do not understand why. The script generates three dialog boxes containing the same message: "Hi There". I have two questions:
1) How can j and k be set to reference i before i is defined?
2) Why does not r reference the i defined in test2?
on test1()
return get a reference to i
end test
on run
set j to test1()
set k to a reference to i
set i to "Hi there"
display dialog j
display dialog k
test2()
end run
on test2()
set i to "now see here"
set r to a reference to i
display dialog r
end test2
Note: The Script Editor is Version 2.7 and the AppleScript Version is 2.4.
This is not an answer to the original question. This is in response to foo’s comment made on December 1. It is an example of how to create two instances of the same script boy which share a common record. Also, having learned from foo's comment, I used a record to share properties with all the script instances. I don’t know if this is the best way to do it, but at least there are no globals.
I feel foo answered my second question on Nov 18. As for the first question, I will offer my own explanation, which I discerned after reading about Object Specifiers. The following statement, taken from my example, contains an implicit
of (get me)
.To illustrate, I will rewrite the statement explicitly.
When either of these statements execute, a reference object is created which contains an object specifier. The phrase between the
a reference to
and theget
is not evaluated, instead it is stored in the object specifier. In this case, the phrase isi of
. What is to the right of theget
is evaluated and this result is also stored in the object specifier. In this case, this result isme
which is the top-level script object. This is why the variablei
does not have to exist, when the reference object is returned from thetest1
handler. When thedisplay dialog j
statement executes, the reference object is fully evaluated. It is at this point the variablei
must exist. This same explanation can be applied to the variablek
shown in my example.I do realize that a text phrase, to be evaluated later, probably is not actually stored in an object specifier. At the very least, I know the phrase is parsed and syntax checked, but the AppleScript Language Guide does not definitely state how the unevaluated part of a statement is stored.
To me, the placement of the implicit
get
seems to be somewhat arbitrary. Let me illustrate my point with some examples. (Here for brevity, I have omitted proofs. If reader(s) can not verify, let me know and I will include proofs)Example 1: If you write
you get
Example 2: If you write
you get
Example 3: If you write
you get
Example 4: If you write
you get
If you wish to set the contents of a reference to a object, I found the following restriction. The number of
in
andof
reserved keywords in a phrase, contained by a object specifier, must equal unity. A total of zero or more than one will result in a script execution error. The example below illustrates this.The log output is given below.
The statement
set contents of r to "bb”
worked because I added an explicitget
to the previous statement. This forced early evaluation of part of the object specifier.Next, I would like to address the question “What is the context you feel like you need to [use references]?” asked by tweaks on Nov 17.
Originally, I was trying to find a way for a handler to return two values through passed parameters. A working example is shown below.
Executing this code produces the log output:
The code, shown above, has two drawbacks: 1) The variables
r
ands
can not be local. 2) The variablesr
ands
have to exist before the handlerFirstAndLast
is called. After working with Applescript for a while, I realize there are better ways to implement this code. One way is to employ pattern assignment as described in the AppleScript Language Guide. The code using pattern assignment is shown below.This version has three advantages. 1) Here no reference objects are used. 2) The identifiers
r
ands
can represent local variables, global variables or properties. 3) If the identifiersr
ands
represent variables, the variables do not have to exist before calling the handlerFirstAndLast
.Finally, evidently handlers are objects. If you think I am wrong, then explain why the following executes.
You can only create references to an object property or element[s], or to global variables (an annoying mis-feature which behave like badly designed properties), not to local variables. e.g. These all work:
All variables within an implicit or explicit
run
handler are global (another mis-feature), unless explicitly declaredlocal
. The combination of those two mis-features is why yourrun
handler example works, even though it looks like it shouldn't.Yeah, it's kind of a janky language. But look on the bright side: it's still less headachey than C pointers.
You basically don't want to create "reference to" in your scripting. The class exists because it is common for a command to return a reference to. The only advantage I can think of using it is that you CAN create a reference to an object, without the class and value of the object being explicitly given. You can then later define the object.
So, in your sample, you CAN create a reference to an object and then later create it.
Inside the test2 handler, a reference to is a global context, so it looks at the identifier i in the run handler, not inside the test2 handler.
I really suggest not using them in your script. What is the context you feel like you need to?