AppleScript参考对象 - 帮助我理解它们

时间:2011-04-28 20:36:46

标签: reference applescript pass-by-reference appleevents

为什么这些甚至存在?这似乎很荒谬。与大多数动态语言一样,AppleScript类型似乎是不可变的原始类型,如integerreal s,它们将按值传递,并且与{{{{{}一起使用没有任何意义。 1}}或类似对象的类型,例如a reference to s,application s或script s,它们已经通过引用传递。 record如何不完全冗余?以下是Apple AppleScript语言指南(http://developer.apple.com/library/mac/#documentation/AppleScript/Conceptual/AppleScriptLangGuide/introduction/ASLR_intro.html如果您丢失链接)的示例:

a reference to

所以你的意思是告诉我,如果我这样做了,

tell app "Finder" to set diskRef to a ref to startup disk
--result: startup disk of application "Finder"

appleScript运行时将发送一个发送到Finder进程的苹果事件告诉它,“嘿 - 有人刚要求你将/ dev / disks01的八位流返回给我!哈哈!我猜他应该问tell app "Finder" to set diskObj to startup disk --result: startup disk of application "Finder" 它!让我们开始吧!这需要一段时间!“

我正在用Python编程,我这样做:

a reference to

我只是在内存中复制了一大堆数据吗?当然不是。但AppleScript中存在m = fileHandle.read( 1000000000 ) #and then wait a little while n = m 意味着将对象分配给新变量是一种按值操作。如果是这样的话,那么a reference to命令的处理是什么?

这里发生了什么?

更新:好吧,只是认为我是一个困惑的Python程序员。为了使这一点更清楚,我仍然认为

copy

是一个糟糕的例子(取自Applecript语言指南)。但是@ Chuck的tell app "Finder" to set diskRef to a ref to startup disk --result: startup disk of application "Finder" 示例属性本身持有一个可以重新分配的原始类型是更好的。 IOW,a reference to对象实际上是一个变量/属性,它包含指向另一个变量或属性的指针。

2 个答案:

答案 0 :(得分:3)

我的理解是你可以将引用视为指针。

set x = 5
set y to reference to x
set contents of y to 10
log x -- 10

通常,您不会手动创建引用。 AppleScript库和字典可能会返回它们,但您可以使用返回项的属性(例如name of startup disk)。

老实说,我会忽略它们。在使用AppleScript的二十年中,我可能不得不一次查阅文档以引用。如果您正在尝试在AppleScript中执行某些操作并且认为需要创建引用变量,那么您可能无法以最直接的方式执行此操作。

查看this MacTech article以获取有关AppleScript参考的更详细讨论。

答案 1 :(得分:1)

AppleScript中的两个变量(如Python)可以共享相同的值。每个变量都有对其值的引用,但“引用”一词具有其他含义。字符串"https://stackoverflow.com/"是对网站的引用;整数42是道格拉斯亚当斯作品的参考; AppleScript中的类reference的对象是一种不同的引用。

reference的对象推迟访问某个对象的元素或属性。它几乎就像Python中的lambda,因为AppleScript

set v to {11, 22, 33}
set r to a reference to item 2 of v

就像Python一样

v = [11, 22, 33]
r = lambda: v[1]

通过推迟访问列表的第2项。然后AppleScript中的contents of r或Python中的r()将获得该项目。 AppleScript还可以使用set contents of r to 99设置项目; Python无法使用此lambda设置项目。 Python的lambdas可以做许多AppleScript的引用无法做到的事情。

a reference to运算符

AppleScript Language Guide 描述了a reference to运算符,但错过了一些重要的细节。运营商有一个操作数;编译器也接受reference OPERANDref OPERAND,然后将其重写为a reference to OPERAND

如果操作数是A of BB's A形式的表达式,则运算符将表达式包装在类reference的对象中。此表达式可以是item 2 of q之类的元素,也可以是length of q等属性。

如果操作数是变量,则运算符附加隐式myof me 。例如,运行处理程序中的a reference to qa reference to my q相同。在qmy q不同的范围内,这会变得令人困惑。

对于其他操作数,则运算符仅返回操作数。例如,a reference to 3返回3,其中不是reference的对象。

运算符捕获变量的当前值。例如,a reference to item i of q捕获i和q的值。相比之下,a reference to q不捕获q的值,因为它与a reference to my q相同,因此它将q视为属性,而不是变量。

to demo()
    set q to {11, 22, 33}
    set rq to a reference to q
    set i to 2
    set ri to a reference to item i of q
    set i to 3
    set item 2 of q to 55
    set q to {77, 88, 99}
    {contents of rq, contents of ri}
end demo

set q to "a string"
demo()

此脚本的结果是{“一个字符串”,55}。引用rq忽略了本地q并使用了运行处理程序中的my q。参考ri捕获了i和q的局部值,忽略了后来对i和q的赋值,但没有忽略q的第2项的赋值。

使用带有大列表的引用

AppleScript语言指南还提供了使用a reference to运算符的示例,以提高对大列表的访问速度。 指南使用

set bigListRef to a reference to bigList

但未能解释该引用是隐式a reference to my bigList,因此访问是通过脚本对象me进行的。它只能起作用,因为代码位于运行处理程序中,其中bigListmy bigList是相同的列表。

事实证明,如果引用通过任何脚本对象,对大列表的访问速度很快。其他访问很慢。下一个脚本通过使用快速访问创建7000个项目列表,然后使用慢速和快速访问读取列表来显示此信息。

to bench(what)
    set start to current date
    repeat with i from 1 to 7000
        if item i of what is not 42 then
            error "wrong value"
        end if
    end repeat
    (current date) - start
end bench

to bench2()
    script box
        property nums : {}
    end script
    repeat 7000 times
        set end of box's nums to 42
    end repeat
    {bench(box's nums), bench(a reference to box's nums)}
end bench2

bench2()

我在运行PowerPC Mac OS X 10.4.11的旧机器上运行此脚本。结果是{19,0},所以慢访问需要19秒,快速访问需要0秒。

set end of box's nums to 42可以在不使用a reference to运算符的情况下快速访问。它很快,因为访问通过box,一个脚本对象。