我觉得 foo 在 11 月 18 日回答了我的第二个问题。至于第一个问题,我将提供我自己的解释,这是我在阅读 Object Specifiers 后发现的。以下语句取自我的示例,包含一个隐含的of (get me)。
return get a reference to i
为了说明,我将明确地重写语句。
return get a reference to i of (get me)
当执行这些语句中的任何一个时,都会创建一个包含对象说明符的引用对象。 a reference to 和 get 之间的短语是不评估的,而是存储在对象说明符中。在这种情况下,短语是i of。评估 get 右侧的内容,并且此结果也存储在对象说明符中。在这种情况下,这个结果是me,它是顶级脚本对象。这就是当引用对象从test1 处理程序返回时,变量i 不必存在的原因。当display dialog j 语句执行时,引用对象被完全评估。此时变量i 必须存在。同样的解释也适用于我的示例中显示的变量k。
我确实意识到稍后要评估的文本短语可能实际上并未存储在对象说明符中。至少,我知道该短语已经过解析和语法检查,但 AppleScript 语言指南并没有明确说明语句中未计算的部分是如何存储的。
对我来说,隐式get 的位置似乎有些随意。让我用一些例子来说明我的观点。 (此处为简洁起见,我省略了证明。如果读者无法验证,请告诉我,我会附上证明)
示例 1:如果你写
set r to a reference to i
你得到
set r to get a reference to i of (get me)
例子2:如果你写
set r to a reference to item 2 of i
你得到
set r to get a reference to item 2 of (get i of me)
示例 3:如果你写
set r to a reference to i of me
你得到
set r to get a reference to i of (get me) -- same as Example 1
示例 4:如果你写
set r to a reference to item 2 of i of me
你得到
set r to get a reference to item 2 of i of (get me) -- differs from Example 2
如果您希望设置对对象的引用的内容,我发现了以下限制。由对象说明符包含的短语中的in 和of 保留关键字的数量必须相等。总数为零或大于一将导致脚本执行错误。下面的例子说明了这一点。
property j : {1, 2, {3, 4}, {{5, {6, 7}}, 8, 9}}
log "Line 1: " & j
set r to a reference to item 3 of j -- phrase is "item 3 of", object is (get j of me)
set contents of r to "aa" -- Succeeds since total count is 1
log "Line 2: " & j
set r to a reference to item 2 of (get item 1 of item 4 of j) -- phrase is "item 2 of", object is (get item 1 of item 4 of (get j of me))
set contents of r to "bb" -- Succeeds since total count is 1
log "Line 3: " & j
set j to {1, 2, {3, 4}, {{5, {6, 7}}, 8, 9}}
log "Line 4: " & j
set r to a reference to item 3 of j of me -- phrase is "item 3 of j of", object is (get me)
try
set contents of r to "cc" -- Fails since total count is 2
on error msg
log "Line 5: " & msg
end try
log "Line 6: " & j
set r to a reference to item 2 of item 1 of item 4 of j -- phrase is "item 2 of item 1 of item 4 of", object is (get j of me)
try
set contents of r to "dd" -- Fails since total count is 3
on error msg
log "Line 7: " & msg
end try
log "Line 8: " & j
日志输出如下。
(*Line 1: 123456789*)
(*Line 2: 12aa56789*)
(*Line 3: 12aa5bb89*)
(*Line 4: 123456789*)
(*Line 5: Can’t set item 3 of j to "cc".*)
(*Line 6: 123456789*)
(*Line 7: Can’t set item 2 of item 1 of item 4 of {1, 2, {3, 4}, {{5, {6, 7}}, 8, 9}} to "dd".*)
(*Line 8: 123456789*)
set contents of r to "bb” 语句有效,因为我在前面的语句中添加了显式的get。这个forced early evaluation 是对象说明符的一部分。
接下来,我想解决“您认为需要 [使用引用] 的上下文是什么?”这个问题。 11 月 17 日通过调整询问。
最初,我试图找到一种方法让处理程序通过传递的参数返回两个值。下面显示了一个工作示例。
set r to missing value
set s to missing value
FirstAndLast(a reference to r, a reference to s, "now is the time for all good men")
log r
log s
on FirstAndLast(alpha as reference, omega as reference, message as text)
set contents of alpha to first word of message
set contents of omega to last word of message
end FirstAndLast
执行此代码会产生日志输出:
(*now*)
(*men*)
上面显示的代码有两个缺点: 1) 变量r 和s 不能是本地的。 2) 在调用处理程序FirstAndLast 之前,变量r 和s 必须存在。使用 Applescript 一段时间后,我意识到有更好的方法来实现此代码。一种方法是使用AppleScript Language Guide 中描述的模式分配。使用模式赋值的代码如下所示。
set {r, s} to FirstAndLast("now is the time for all good men")
log r
log s
on FirstAndLast(message as text)
set alpha to first word of message
set omega to last word of message
return {alpha, omega}
end FirstAndLast
此版本具有三个优点。 1) 这里没有使用参考对象。 2)标识符r和s可以表示局部变量、全局变量或属性。 3)如果标识符r和s代表变量,则在调用处理程序FirstAndLast之前变量不必存在。
最后,显然处理程序是对象。如果您认为我错了,请解释为什么会执行以下操作。
on test()
log class of test as text
end test
property y : test
set x to test
log class of x as text
log class of y as text
x()
y()