AppleScript 参考对象 - 帮助我理解它们
为什么这些甚至存在?这似乎很荒谬。与大多数动态语言一样,AppleScript 类型似乎是不可变的原始类型,例如整数和实数,它们将按值传递,并且不会产生任何影响。与引用
或类似对象类型(例如应用程序
、脚本
或记录
)一起使用的意义s,它们已经通过引用传递。 对
的引用为何不完全多余?以下是摘自 Apple 的 AppleScript 语言指南 ( https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html):
tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"
所以你的意思是告诉我,如果我这样做,
tell app "Finder" to set diskObj to startup disk
--result: startup disk of application "Finder"
applescript运行时将向 Finder 进程发送一个苹果事件,告诉它,“嘿 - 有人刚刚要求你将 /dev/disks01 的八位字节流返回给我!哈哈!我想他应该要求 参考
让我们开始吧!”
我正在用 Python 编程,我这样做:
m = fileHandle.read( 1000000000 ) #and then wait a little while
n = m
我是否刚刚在内存中复制了一大堆数据?当然不是。但 AppleScript 中引用
的存在意味着将对象分配给新变量是一种按值操作。如果是这样的话,复制命令是怎么回事?
这是怎么回事?
更新:好吧,就当我是一个困惑的 Python 程序员吧。为了让这一点更清楚,我仍然认为
tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"
这是一个糟糕的例子(取自 applescript 语言指南)。但 @Chuck 的对属性本身的引用
的示例持有一个可以重新分配的原始类型,这是一个更好的例子。 IOW,引用对象实际上是一个变量/属性,它保存指向另一个变量或属性的指针。
Why do these even exist? It seems absurd. Like with most dynamic languages, AppleScript types seem to be either immutable primitive types like integer
s and real
s which are going to be handed around by value and don't make any sense to use with a reference to
, or object-like types like application
s, script
s, or record
s, which are being passed around by reference already. How is a reference to
not completely redundant? Here's an example taken from Apple's AppleScript Language Guide (https://developer.apple.com/library/archive/documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html):
tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"
So do you mean to tell me that if I did this instead,
tell app "Finder" to set diskObj to startup disk
--result: startup disk of application "Finder"
that the applescript runtime is going to send an apple event sent across to the Finder process telling it, "hey - some guy just asked you to return an octet stream of /dev/disks01 back to me! Haha! I guess he should have asked for a reference to
it! Let's get started! This is going to take a while!"
I'm programming in Python and I do this:
m = fileHandle.read( 1000000000 ) #and then wait a little while
n = m
Did I just copy a gig of data around in memory? Of course not. But the existence of a reference to
in AppleScript implies that assigning objects to new variables is a by-value operation. And if that's the case, what's the deal with the copy
command?
What's going on here?
UPDATE: Well, just consider me a confused Python programmer. Just to make this a bit more clear, I still think
tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"
is a poor example (taken from the applescript language guide). But @Chuck's example of a reference to
the property itself holding a primitive type that can then be reassigned is a better one. IOW, a reference
object is really a variable/property that holds a pointer to another variable or property.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
AppleScript 中的两个变量(与 Python 中一样)可以共享相同的值。每个变量都有对其值的引用,但“引用”一词还有其他含义。字符串
"https://stackoverflow.com/"
是对网站的引用;整数42
引用了 Douglas Adams 的作品; AppleScript 中reference
类的对象是一种不同类型的引用。reference
类的对象推迟对某个对象的元素或属性的访问。它几乎就像 Python 中的 lambda,因为 AppleScript 的行为与 Python 类似
,推迟对列表第二项的访问。然后 AppleScript 中的 r 内容或 Python 中的 r() 内容将获取该项目。 AppleScript 还可以通过
将 r 的内容设置为 99
来设置该项目; Python 无法使用此 lambda 设置项目。 Python 的 lambda 表达式可以做许多 AppleScript 引用无法做的事情。对
运算符的引用AppleScript 语言指南描述了
对
运算符的引用,但遗漏了一些重要的细节。运算符只有一个操作数;编译器还接受引用OPERAND
或ref OPERAND
,然后将它们重写为对OPERAND的引用
。如果操作数是
A of B
或B's A
形式的表达式,则运算符将表达式包装在reference
类的对象中。该表达式可以是一个元素,例如q 的第 2 项
,也可以是一个属性,例如q 的长度
。如果操作数是变量,则运算符附加隐式
my
或of me
。例如,运行处理程序中对 q 的引用
与对 my q 的引用
相同。在q
和my q
不同的范围内,这会变得令人困惑。对于其他操作数,则运算符仅返回操作数。例如,
对 3 的引用
返回 3,它不是引用
类的对象。运算符捕获变量的当前值。例如,
对 q 的项 i 的引用
捕获 i 和 q 的值。相比之下,对 q 的引用
不会捕获 q 的值,因为它与对我的 q 的引用
相同,因此它将 q 视为属性,不是一个变量。该脚本的结果是 {"a string", 55}。引用 rq 忽略本地 q 并使用运行处理程序中的
my q
。引用 ri 捕获了 i 和 q 的局部值,忽略了后来对 i 和 q 的赋值,但没有忽略对 q 的第 2 项的赋值。对大列表使用引用
AppleScript 语言指南还提供了使用
引用
运算符来提高访问大列表速度的示例。 指南使用但未能解释该引用隐式
对我的bigList的引用
,因此访问是通过脚本对象me
进行的。它之所以有效,是因为代码位于运行处理程序中,其中bigList
和my bigList
是相同的列表。事实证明,如果引用经过任何脚本对象,则对大列表的访问会很快。其他访问速度很慢。下一个脚本通过使用快速访问创建包含 7000 个项目的列表,然后使用慢速和快速访问读取该列表来显示这一点。
我在运行 PowerPC Mac OS X 10.4.11 的旧机器上运行了这个脚本。结果是{19, 0},所以慢速访问用了19秒,快速访问用了0秒。
set end of box's nums to 42
行无需使用引用
运算符即可进行快速访问。它速度很快,因为访问是通过脚本对象box
进行的。Two variables in AppleScript, like in Python, can share the same value. Each variable has a reference to its value, but the word "reference" has other meanings. The string
"https://stackoverflow.com/"
is a reference to a web site; the integer42
is a reference to the works of Douglas Adams; and an object of classreference
in AppleScript is a different kind of reference.An object of class
reference
postpones access to an element or property of some object. It's almost like a lambda in Python, because the AppleScriptacts like the Python
by postponing access to the 2nd item of a list. Then
contents of r
in AppleScript orr()
in Python would get the item. AppleScript can also set the item withset contents of r to 99
; Python can't set the item with this lambda. Python's lambdas can do many things that AppleScript's references can't do.a reference to
operatorThe AppleScript Language Guide describes the
a reference to
operator but misses some important details. The operator has one operand; the compiler also acceptsreference OPERAND
orref OPERAND
, then rewrites them asa reference to OPERAND
.If the operand is an expression of the form
A of B
orB's A
, then the operator wraps the expression in an object of classreference
. This expression can be an element, likeitem 2 of q
, or a property, likelength of q
.If the operand is a variable, then the operator attaches an implicit
my
orof me
. For example,a reference to q
in the run handler is the same asa reference to my q
. This becomes confusing in scopes whereq
andmy q
are different.For other operands, then the operator only returns the operand. For example,
a reference to 3
returns 3, which is not an object of class ofreference
.The operator captures the current value of variables. For example,
a reference to item i of q
captures the values of i and q. For contrast,a reference to q
doesn't capture the value of q, because it is the same asa reference to my q
, so it sees q as a property, not a variable.The result of this script is {"a string", 55}. Reference rq ignored the local q and used
my q
from the run handler. Reference ri captured the local values of i and q, ignored later assignments to i and q, but didn't ignore the assignment to item 2 of q.Using references with big lists
The AppleScript Language Guide also has examples using the
a reference to
operator to increase the speed of accesses to a big list. The Guide usesbut fails to explain that the reference is implicitly
a reference to my bigList
, so the access is through the script objectme
. It only works because the code is in the run handler, wherebigList
andmy bigList
are the same list.It turns out that accesses to a big list are fast if the reference goes through any script object. Other accesses are slow. The next script shows this by creating a list of 7000 items using fast accesses, and then reading the list using both slow and fast accesses.
I ran this script on my old machine running PowerPC Mac OS X 10.4.11. The result was {19, 0}, so the slow accesses took 19 seconds, and the fast accesses took 0 seconds.
The line
set end of box's nums to 42
does a fast access without using thea reference to
operator. It is fast because the access goes throughbox
, a script object.我的理解是,您可以将引用视为指针。
通常,您不会手动创建引用。 AppleScript 库和字典可能会返回它们,但随后您将使用返回项的属性(例如
启动磁盘的名称
)。老实说,我会忽略他们。在使用 AppleScript 的二十年中,我可能不得不查找一次文档以获取参考资料。如果您尝试在 AppleScript 中执行某些操作并认为需要创建引用变量,那么您可能不会以最直接的方式执行此操作。
请查看这篇 MacTech 文章了解更多详细信息AppleScript 参考文献的讨论。
My understanding is that you can think of references as pointers.
In general, you don't manually create references. AppleScript libraries and dictionaries may return them, but then you work with the properties of the returned item (
name of startup disk
for example).Honestly, I'd ignore them. In twenty years of working with AppleScript, I've probably had to look up the documentation to references once. If you're trying to do something in AppleScript and believe you need to create a reference variable, you're probably not doing it in the most straightforward manner.
Check out this MacTech article for a more detailed discussion of AppleScript references.