避免的AppleScript通过红宝石:RB-appscript或rubyosa?(Avoiding

2019-06-18 16:42发布

你好老乡Mac的Ruby开发者和AppleScript仇敌,

对于那些有经验有两个rubyosa和RB-appscript,我想听到的每一个优点和缺点,你决定坚持哪一个,哪一个你会推荐一个完全非AppleScript的精明红宝石老前辈。 此外,是否有我错过任何其他的选择吗?

顺便说一句,应付式的AppleScript的侧任何提示(例如浏览词典等)也欢迎。

看到一些示例代码也有很大帮助。

Answer 1:

答曰KCH:

这很好,但现在我很好奇如何脚本桥比较的AppleScript。 我想我还会有一些读书的事情。

SB省略了AppleScript的发现了一些功能。 例如,下面的脚本从桌面到Documents文件夹移动所有文件:

tell application "Finder"
   move every file of desktop to folder "Documents" of home
end tell

在SB中,SBElementArray类严重限制了你的申请一个命令到多个目标的能力,让你无论是不得不求助于低级别的API或者获得单独的文件引用的列表和移动这些一次一个:

require 'osx/cocoa'; include OSX
require_framework 'ScriptingBridge'

finder = SBApplication.applicationWithBundleIdentifier('com.apple.finder')
destination = finder.home.folders.objectWithName('Documents')
finder.desktop.files.get.each do |f|
   f.moveTo_replacing_positionedAt_routingSuppressed(destination, nil, nil, nil)
end

在RB-appscript,你会用同样的方式为AppleScript的:

require 'appscript'; include Appscript

app("Finder").desktop.files.move(:to => app.home.folders["Documents"])

...

SB更重比的AppleScript的确混淆了苹果事件机制。 AppleScript的可以是一个痛苦让你的头部周围,有什么奇怪的语法,倾向关键字冲突等,但除此之外,它在很大程度上呈现苹果事件原样。 在作为唯一真正显著片神奇的是它的“隐式获取”行为时,它的计算结果是不会出现作为参数的命令的字面参考。 AppleScript的最大的罪过是,它的文档没有更好的解释它是如何工作,但有一个由威廉·库克非常好纸是揭示轻了不少关于什么实际事情。

SB,而另一方面,做它的最难假装它是一个真正的可可API与可可风格的行为,因此在大量的魔法层。 其结果是表面上的东西吸引Cocoa开发,但只要这些抽象开始泄漏 - 作为抽象总是做 - 你完全在海上的理解发生了什么条款。 例如,SBElementArray声称自己是一个数组 - 它甚至子类NSMutableArray的 - 但是当你真正尝试使用它的阵列的方法,其中有一半工作,其中一半没有。 事实上,它是不是在所有真正的数组; 这是围绕一个未计算的苹果事件对象说明符的包装,伪造高达假装这是一个NSMutableArray。 因此,当它做了非阵列状,你主要是为酿理解为什么。 而且,在#1提到,一些厚抽象的,难以访问下面的标准苹果事件的功能。

SB firstmost尝试是一个很好的可可API,而不是一个很好的苹果事件的API,并最终成为不太擅长无论是。

Appscript,顺便说一下,下面的AppleScript的领先优势,并采取了相反的做法:苹果做活动的权利,然后担心容纳宿主语言。 这就是为什么有些人喜欢RubyOSA在RB-appscript; 而appscript是更强大的解决方案,如果你已经从一个严重的面向对象的背景的人,会觉得很奇怪。 这是因为苹果事件使用RPC加基于查询的范例,任何相似之处appscript可能不得不OOP是纯粹的语法。 最近的类比是在XML-RPC发送XQuery查询,这需要一些时间来适应。

...

SB往往承受着比其他的AppleScript显著多个应用程序兼容性问题。

其中有些问题是由于SB强加了自己的苹果如何事件IPC 应该在它如何实际工作顶部工作思路。 例如,SB产生一组表示在字典中定义的类[伪]代理类; 然后,它规定了如何通过主要基于经典的面向对象的行为规则,这些对象交互的各种限制。

例如,下面的脚本得到的文档文件夹的所有子文件夹的名称:

tell application "Finder"
   get name of every folder of entire contents of folder "Documents" of home
end tell

如果试图在SB相同的方法:

finder.home.folders.objectWithName('Documents').entireContents.folders.arrayByApplyingSelector(:name)

它得到尽可能的#folders方法,那么因为“全部内容”属性的Finder的字典中的类型被声明为“参考”抛出一个错误。 由于没有在字典中定义的“文件夹”元素“参考”类,SB不会让你构建一个特定的查询(除非你要下降到低级别的API,并且使用原料AE码)。 这是完全合法的,根据苹果事件的规则,而是由SB规定的窄OO为中心的规则集内不适合。

其他错误是由于某人作出有关编写脚本的应用程序将如何执行某些命令和其他功能的假设。 例如:

tell application "iTunes"
   make new playlist with properties {name:"test 1"}
end tell

SB不会让你带由iTunes提供任何快捷方式的优势,但(你可以省略参考这种情况下,主要的“库”源用于所需的播放列表创建的源对象),所以让我们写在全力为更好的比较:

tell application "iTunes"
   make new playlist at source "Library" with properties {name:"test"}
end tell

在SB你会写为:

itunes = SBApplication.applicationWithBundleIdentifier('com.apple.itunes')

playlists = itunes.sources.objectAtIndex(0).playlists()
newplaylist = itunes.classForScriptingClass(:playlist).alloc().initWithProperties({:name => 'test'})
playlists.addObject(newplaylist)

当你虽然运行它,它barfs上#addObject。 在试图把一个单一的“使”命令到多线运动,SB假定“在”参数将始终为的形式“的<对象> <元素>”端的参考,这是怎么可可脚本基于应用程序做到这一点。 Carbon应用程序没有因为虽然实现苹果事件支持一个单一的标准框架,所以他们往往变化多一点在他们的要求。 iTunes中,例如,需要一个参考容器对象,在这种情况下“源‘库’”,并且当SB传递“源的播放列表的末尾‘库’”不喜欢它。 这是一个很大的AppleScriptable应用程序是如何的,但SB无视这一现实,下定决心要“面向对象”。

然而,当一个应用程序字典不是100%精确的或详细穷尽更多的问题引起的。 无论是aete也不sdef格式允许你描述应用程序的脚本接口在100%细节是如何工作的; 有些事是必须在用户进行猜测,或者补充文件中描述的 - 的Finder的“全部内容”属性就是一个例子性质。 其他信息,如哪些对象的类可以是其他类的对象,以及每个属性的类型,则从来没有真正使用的AppleScript本身的元素 - 这是完全有用户文档。 由于AppleScript的不依赖于这些信息,任何错误将测试针对AppleScript的应用程序的脚本支持时,因为脚本工作得很好,尽管它错过了。 SB并使用这些信息,所以任何错别字出现将导致丢失或需要再次下降到低级别的API来规避断功能。

Appscript,顺便说一句,是不是100%“的AppleScript兼容”要么,但它确实来了一个可怕的很多接近。 appscript的早期版本也试图强加给苹果事件,如执行字典定义的对象模型中的各种OO规则,但一年运行到应用程序不兼容后,我ganked所有的“聪明”的代码,并在接下来的几年努力黑盒子反向工程的AppleScript的内部阴谋,使appscript尽可能接近模仿他们尽可能。 “如果你不能打败他们(你不能),就加入他们”,换句话说。 并在appscript不打的兼容性问题,通常有它周围的方式,包括翻转内部兼容性设置,然后导出应用术语的模块,由专人修补它,并使用替代,或下降到低级别的原料AE码蜜蜂。

...

FWIW,我也应该插上一些相关appscript东西。

首先,在appscript网站ASDictionary和ASTranslate工具是你的朋友。 ASDictionary将导出appscript风格的HTML格式的应用程序词典,还支持内置的RB-appscript#帮助方法; 非常适合在IRB互动发展。 ASTranslate将采取一个AppleScript命令(错误愿)在appscript语法返回等效的命令。

其次,RB-appscript的源代码分发同时包含文档和示例脚本。 如果你安装了appscript宝石,记得要抢这些资源的zip分发为好。

第三, 马特·诺伊堡写了一本关于RB-appscript 。 去阅读它,如果你想使用RB-appscript的。 而去读博士库克的论文,无论你最终决定。

...

不管怎么说,希望有所帮助。 (呵呵,对于长道歉,但我刚刚写了这个星期约25000字,所以这只是一些轻放松。)

PS斯内德,你有光泽美元是在后。 ;)



Answer 2:

我没有试过RubyOSA,但我已经取得了巨大成功RB-appscript 。 它完美地工作对我来说,比使用AppleScript直接合作好得多。

你见过这个线程两相比较 ? 它有一个很好的详细解答注意的差异。



Answer 3:

苹果包括通过一个名为“脚本桥”框架可可兼容语言的脚本支持。 我使用通过RubyCocoa / MacRuby的我的脚本的需求。 它包括正确的盒子,所以这是很方便的。

require 'osx/cocoa'
require_framework 'ScriptingBridge'
iTunes = SBApplication.applicationWithBundleIdentifier 'com.apple.iTunes'
puts iTunes.selection.name

唯一的主要烦恼我发现脚本大桥是,你必须使用的包ID一样,而不是名称,但这是不是真的太大的问题,对我来说反正。 它也只包括10.5英寸,所以如果你需要豹,老虎的支持,你需要别人的一个。

另外两个,RB-appscript仍然在继续开发,而RubyOSA得到有效几年前冻结,所以我可能会与前走。 随着Ruby 2,MacRuby的和其他新的实现带来的语言变化,RB-appscript更可能在今后的工作。 否则,他们很相似。 我基本上是把RB-appscript像RubyOSA的一个新的版本,虽然它不是技术上是真实的。



Answer 4:

简短的回答:RB-appscript。

由于脚本桥似乎是一个烂摊子,RubyOSA已经停产。



文章来源: Avoiding AppleScript through Ruby: rb-appscript or rubyosa?