【问题标题】:How to update AppleScript List "Forever"如何更新 AppleScript 列表“永远”
【发布时间】:2018-06-29 23:16:08
【问题描述】:

看下面的代码:

set TheStringsQ1Happy to {"Fabulous", "Great", "Alright", "Excited", "Not Bad", "", "Decent", "Fine", "Awesome", "Bored", "Cool", "Sad", "Fantastic", "Alright", "Good", "Ok"}

set theResponse to the text returned of (display dialog "" default answer "" giving up after 5)

if TheStringsQ1Happy contains theResponse then 
    display dialog "That's Great!" 
else
    say "That term is not in my vocabulary. Would you like me to add it?" using "Tom" speaking rate 220
    set theResponseNotInVocabulary to text returned of (display dialog "" default answer "" giving up after 5)

    if theResponseNotInVocabulary is "Yes" then 
       set end of TheStringsQ1Happy to theResponse
       return TheStringsQ1Happy
   end if

虽然我可以更新TheStringsQ1Happy,但此更新仅持续脚本的跨度。如何更改代码,以便每次运行脚本时,它也包含更新的词汇表?

例如,如果我说“All Good”,计算机会识别出词汇表不在列表中,并且稍后会仅针对该实例更新此列表。我怎样才能让它从现在开始在每个实例中都保持“All Good”?

【问题讨论】:

    标签: macos scripting applescript automator


    【解决方案1】:

    以下是一个严格的示例,旨在帮助您解决您的问题,而不是修复您发布的损坏代码。

    如果您在脚本编辑器中运行以下命令:

    property theList : {1, 2, 3}
    copy (count theList) + 1 to end of theList
    log theList
    

    您将看到 theList 每次运行它时,property 都会增长 1,直到重新编译脚本为止。

    如果您需要绝对的长期存储,添加到列表中的任何内容都不会丢失,那么您需要保存到磁盘文件并从磁盘文件中检索。

    【讨论】:

      【解决方案2】:
      AppleScript 中的

      变量 不会超出定义它们的脚本的执行时间,正如您已经注意到的那样。

      但是,属性可以并且将继续使用上一次执行留下的信息继续执行脚本的后续执行。

      但请记住,每次重新编译脚本(每当您对其进行编辑或触发时都会发生这种情况),属性 将被重置(恢复到其原始值)手动编译)。

      考虑到这一点,改变这一行:

      set TheStringsQ1Happy to {"Fabulous", "Great", "Alright", "Excited", "Not Bad", "", "Decent", "Fine", "Awesome", "Bored", "Cool", "Sad", "Fantastic", "Alright", "Good", "Ok"}
      

      到这里:

      property TheStringsQ1Happy : {"Fabulous", "Great", "Alright", "Excited", "Not Bad", "", "Decent", "Fine", "Awesome", "Bored", "Cool", "Sad", "Fantastic", "Alright", "Good", "Ok"}
      

      你会很高兴的。


      如果您想要一种更永久的方法来确保不会意外丢失此属性的新增内容,例如当您需要对脚本进行任何更改以重置其值时,您将需要将信息存储在一个外部文件中,该文件将用作一种词汇术语的“字典”。

      最简单的方法是创建一个文本文件并将列表中的每一项放在单独的行中,如下所示:

      Fabulous
      Great
      Alright
      Excited
      ...etc.
      

      将其保存为 HappyTerms.txt 之类的文件,例如您的 Documents 文件夹,然后将 TheStringsQ1Happy 的变量声明更改为:

      set TheStringsQ1Happy to the paragraphs of (read "/Users/%you%/Documents/HappyTerms.txt")
      

      %you% 替换为 Documents 文件夹所在的 Home 文件夹的名称。事实上,提前将此文本文件的路径放在它自己的变量定义中是一个有用的想法:

      set VocabDictionary to "/Users/%you%/Documents/HappyTerms.txt"
      set TheStringsQ1Happy to the paragraphs of (read VocabDictionary)
      

      最后,要更改此文件并在此行之后立即添加新术语:

      if theResponseNotInVocabulary is "Yes" then set end of TheStringsQ1Happy to theResponse
      

      只需添加任一这些行:

      set AppleScript's text item delimiters to return
      write (TheStringsQ1Happy as text) to VocabDictionary starting at 1
      

      这一行

      write "\n" & theResponse to VocabDictionary starting at (get eof VocabDictionary) + 1
      

      第一个版本用新列表中的所有术语覆盖整个文件。第二个版本只是将新添加的内容附加到文件末尾。您可能希望同时尝试这两种方法并让文件按照您想要的方式运行,因为您会偷偷地发现一个可能在文件中给您一个杂散的空白行,这会无害地导致列表中出现空字符串“”;而另一个没有;但我会让你弄清楚这是否会发生以及为什么会发生,以及——如果你真的不希望它发生——如何防止它。 ? 不管怎样,它不应该给你带来任何问题。

      如果您有任何其他疑问,请发表评论,我会回复您。如果这有帮助,别忘了给我的答案 +1,如果能帮您解决问题,请标记为“正确”。

      【讨论】:

        【解决方案3】:

        这适用于我使用最新版本的 Sierra

        如果将此脚本保存为应用程序,并且您启动此新应用程序...每次将新项目添加到列表中时,每次重新打开应用程序时,该新项目都会保留在列表中。但是,如果您在脚本编辑器中再次打开应用程序,编辑代码并重新保存...您将丢失添加的列表项的所有值并且整个循环从默认列表重新开始。

        property TheStringsQ1Happy : {"Fabulous", "Great", "Alright", "Excited", "Not Bad", "", "Decent", "Fine", "Awesome", "Bored", "Cool", "Sad", "Fantastic", "Alright", "Good", "Ok"}
        
        set theResponse to (display dialog "How Do You Feel Today?" default answer "" giving up after 25)
        
        if text returned of theResponse is in TheStringsQ1Happy then
            display dialog "That's Great!"
        else
            say "That term is not in my vocabulary. Would you like me to add it?" using "Tom" speaking rate 220
            set theResponseNotInVocabulary to display dialog "Add This Term" & " " & quote & text returned of theResponse & quote & " " & "To My Vocabulary?" buttons {"No", "Yes"} default button 2
            if the button returned of the result is "Yes" then
                if TheStringsQ1Happy does not contain text returned of theResponse then
                    set end of TheStringsQ1Happy to text returned of theResponse
                end if
                return TheStringsQ1Happy
            end if
        end if
        

        【讨论】:

        • 在重复现有答案之前,您是否不先检查其他人是否还没有提供完全相同的解决方案?我觉得这既是礼仪问题,也是冗余问题。
        • @CJK 当我开始解决 OP 时,还没有答案。在 30 分钟编写、调整和测试我的代码后,我回来发布我的答案并看到已经提供了另外两个答案。在阅读了这些答案后,我觉得我的答案有足够的差异,值得提供我的解决方案作为另一个答案。我的解决方案还更进一步,解决了运行 OP 代码时显示的空对话框。另外,没有冒犯,但真的……当我这样做的唯一原因只是为了帮助别人时,你是谁来评论我的礼仪?
        • 我同意很遗憾,您花时间专注于与 OP 的原始问题无关的代码方面,但相关的解决方案相同 我的答案的一半,即定义一个属性而不是一个变量。礼仪问题与帮助某人的愿望完全无关,所以我看不出你正在建立的联系。但是,我也不想陷入琐碎的争论中,所以我将把它留在那里,因为我觉得我已经表达了我的观点。我很高兴你对此事有最后的发言权。
        • 我同意,如果我的回答是将变量更改为属性,那将与您的回答重复且不必要。但是,纵观全局,OP 包含需要解决的代码。意识到 OP 不熟悉声明属性的好处,很有可能他还需要其他领域的帮助。本着帮助的精神,我拿走了他的代码并重写了它以使其正常运行。如果不出意外,他可以将他的代码与我的代码进行比较,并且可能会从看到差异中受益。
        • 坦率地说,我认为这值得喝啤酒和拍拍背 LOL
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多