Reference 如何在定义Applescript对象之前引用它们?

Reference 如何在定义Applescript对象之前引用它们?,reference,scope,applescript,Reference,Scope,Applescript,有人知道为什么这个applescript有效吗?我不明白为什么。该脚本生成三个对话框,其中包含相同的消息:“您好”。我有两个问题: 1) 在定义i之前,如何将j和k设置为参考i 2) 为什么r不引用test2中定义的i 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 dia

有人知道为什么这个applescript有效吗?我不明白为什么。该脚本生成三个对话框,其中包含相同的消息:“您好”。我有两个问题:

1) 在定义i之前,如何将j和k设置为参考i

2) 为什么r不引用test2中定义的i

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

注意:脚本编辑器版本为2.7,AppleScript版本为2.4。

您基本上不希望在脚本中创建“引用”。该类的存在是因为命令返回对该类的引用是常见的。我能想到的使用它的唯一优点是,您可以创建对对象的引用,而无需显式地给出对象的类和值。然后,您可以稍后定义该对象

  • 因此,在示例中,您可以创建对对象的引用,然后稍后再创建它

  • 在test2处理程序中,对的引用是一个全局上下文,因此它在运行处理程序中查看标识符i,而不是在test2处理程序中

  • 我真的建议不要在你的剧本中使用它们。你觉得你需要什么样的环境

  • 您只能创建对对象属性或元素的引用,或对全局变量的引用(一种令人讨厌的mis功能,其行为类似于设计糟糕的属性),而不能创建对局部变量的引用。e、 g.所有这些都起作用:

    on test2()
        set x to {i:"now see here"}
        set r to a reference to i of x
        display dialog r
    end test2
    
    test2()
    
    on test3()
        set x to {"now see here"}
        set r to a reference to item 1 of x
        display dialog r
    end test3
    
    test3()
    
    on test4()
        script x
            property i : "now see here"
        end script
        set r to a reference to i of x
        display dialog r
    end test4
    
    test4()
    
    
    property i : "now see here"
    
    on test5()
        set r to a reference to i
        display dialog r
    end test4
    
    test5()
    
  • 隐式或显式
    run
    处理程序中的所有变量都是全局变量(另一个mis功能),除非显式声明为
    local
    。这两个mis特性的结合就是为什么您的
    run
    处理程序示例可以工作的原因,尽管它看起来不应该工作


  • 是的,这是一种简陋的语言。但从好的方面来看:这仍然比C点更令人头痛。

    我觉得foo在11月18日回答了我的第二个问题。关于第一个问题,我将提供我自己的解释,这是我在阅读了有关的文章后发现的。下面的语句取自我的示例,包含(get me)的隐式

    为了举例说明,我将明确重写该语句

    return get a reference to i of (get me)
    
    当这些语句执行时,将创建一个包含对象说明符的引用对象。
    的引用和
    获取
    之间的短语不会计算,而是存储在对象说明符中。在这种情况下,短语是
    i of
    。计算
    get
    右侧的内容,该结果也存储在对象说明符中。在本例中,这个结果是
    me
    ,它是顶级脚本对象。这就是当引用对象从
    test1
    处理程序返回时,变量
    i
    不必存在的原因。当执行
    显示对话框j
    语句时,将完全评估参考对象。此时变量
    i
    必须存在。同样的解释也适用于我的示例中所示的变量
    k

    我确实意识到,稍后要计算的文本短语可能实际上并没有存储在对象说明符中。至少,我知道这个短语是经过解析和语法检查的,但是AppleScript语言指南并没有明确说明如何存储语句中未赋值的部分

    对我来说,隐式的
    get
    的位置似乎有些随意。让我用一些例子来说明我的观点。(为了简洁起见,我省略了校样。如果读者无法验证,请告诉我,我将包括校样)

    例1:如果你写

    set r to a reference to i
    
    set r to a reference to item 2 of i
    
    set r to a reference to i of me
    
    set r to a reference to item 2 of i of me
    
    你得到

    set r to get a reference to i of (get me)
    
    set r to get a reference to item 2 of (get i of me)
    
    set r to get a reference to i of (get me) -- same as Example 1
    
    例2:如果你写

    set r to a reference to i
    
    set r to a reference to item 2 of i
    
    set r to a reference to i of me
    
    set r to a reference to item 2 of i of me
    
    你得到

    set r to get a reference to i of (get me)
    
    set r to get a reference to item 2 of (get i of me)
    
    set r to get a reference to i of (get me) -- same as Example 1
    
    例3:如果你写

    set r to a reference to i
    
    set r to a reference to item 2 of i
    
    set r to a reference to i of me
    
    set r to a reference to item 2 of i of me
    
    你得到

    set r to get a reference to i of (get me)
    
    set r to get a reference to item 2 of (get 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 i
    
    set r to a reference to item 2 of i
    
    set r to a reference to i of me
    
    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
    
    如果希望设置对象引用的内容,我发现以下限制。由对象说明符包含的短语中的
    保留关键字的
    数量必须相等。总共零个或多个将导致脚本执行错误。下面的例子说明了这一点

    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*)
    
    语句
    将r的内容设置为“bb”
    有效,因为我在前面的语句中添加了一个显式的
    get
    。这是对象说明符的一部分

    接下来,我想回答tweaks在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
    
    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 
    
    执行此代码将生成日志输出:

    (*now*)
    (*men*)
    
    上面显示的代码有两个缺点:1)变量
    r
    s
    不能是本地的。2)变量
    r
    s
    必须在调用处理程序
    first和last
    之前存在。在使用Applescript一段时间后,我意识到有更好的方法来实现此代码。一种方法是如中所述使用模式分配。使用模式分配的代码如下所示

    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
    
    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
    表示变量,则在调用处理程序
    FirstAndLas之前,变量不必存在t

    最后,处理程序显然是对象。如果您认为我错了,那么请解释为什么执行以下命令

    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()
    

    这不是对原始问题的回答。这是对foo在12月1日发表的评论的回应。这是一个如何创建同一脚本男孩的两个实例的示例,它们共享一个公共记录。此外,从foo的评论中学习,我使用一个记录与所有脚本实例共享属性。我不知道这是否是b这是最好的方法,但至少没有全局的

    script mom
        property hair : "blond"
        property shared : {address:"12 walnut st", phone:"555-1234"}
    end script
    
    script boy
        property parent : mom
    end script
    
    script girl
        property parent : mom
    end script
    
    on clone from old given shared:sharedSwitch as boolean : false
        if sharedSwitch then
            set shared to shared of old
            set shared of old to missing value
        end if
        copy old to new
        if sharedSwitch then
            set shared of new to shared
            set shared of old to shared
        end if
        return new
    end clone
    
    property myboy : clone from boy with shared
    
    on run
        log "mom hair is" & tab & tab & hair of mom
        log "boy hair is " & tab & tab & hair of boy
        log "girl hair is " & tab & tab & hair of girl
        log "myboy hair is " & tab & hair of myboy
        set hair of boy to "redhead"
        log "**Set boy hair to redhead**"
        log "mom hair is" & tab & tab & hair of mom
        log "boy hair is " & tab & tab & hair of boy
        log "girl hair is " & tab & tab & hair of girl
        log "myboy hair is " & tab & hair of myboy
        set hair of myboy to "flattop"
        log "**Set myboy hair to flattop**"
        log "mom hair is" & tab & tab & hair of mom
        log "boy hair is " & tab & tab & hair of boy
        log "girl hair is " & tab & tab & hair of girl
        log "myboy hair is " & tab & hair of myboy
        log
        log "mom phone is" & tab & phone of shared of mom
        log "boy phone is" & tab & phone of shared of boy
        log "girl phone is" & tab & phone of shared of girl
        log "myboy phone is" & tab & phone of shared of myboy
        set phone of shared of myboy to "555-9999"
        log "**Set myboy phone to 555-9999**"
        log "mom phone is" & tab & phone of shared of mom
        log "boy phone is" & tab & phone of shared of boy
        log "girl phone is" & tab & phone of shared of girl
        log "myboy phone is" & tab & phone of shared of myboy
    end run
    
    “全瓦里亚