kch*_*kch 16 ruby macos applescript rb-appscript rubyosa
您好Mac Mac rubyists和AppleScript仇恨,
对于那些有rubyosa和rb-appscript经验的人,我希望听到每个人的优点和缺点,你决定坚持哪一个,以及你推荐哪一个完全非AppleScript精明的人红宝石老人.此外,还有其他任何我错过的选择吗?
另外,任何处理AppleScript方面的提示(例如浏览词典等)也是受欢迎的.
看到一些示例代码也有很大帮助.
小智 46
Quoth kch:
这很好,但现在我很好奇脚本桥如何与applescript相比.我想我会做一些阅读.
SB省略了AppleScript中的一些功能.例如,以下脚本将所有文件从桌面移动到Documents文件夹:
tell application "Finder"
move every file of desktop to folder "Documents" of home
end tell
Run Code Online (Sandbox Code Playgroud)
在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
Run Code Online (Sandbox Code Playgroud)
在rb-appscript中,您使用与AppleScript相同的方法:
require 'appscript'; include Appscript
app("Finder").desktop.files.move(:to => app.home.folders["Documents"])
Run Code Online (Sandbox Code Playgroud)
...
SB比AppleScript更加重视Apple事件机制.AppleScript可能是一个很难理解的问题,奇怪的语法,关键字冲突倾向等等,但除此之外,它主要是按原样呈现Apple事件.AS中唯一非常重要的魔术是它在评估不作为命令参数出现的文字引用时的"隐式get"行为.AppleScript最大的罪恶是它的文档不能更好地解释它的实际工作方式,但是威廉库克有一篇非常好的论文,它揭示了实际发生的事情.
另一方面,SB最难以假装它是一个具有Cocoa风格行为的真正的Cocoa API,因此层层叠加了很多魔法.结果是对Cocoa开发人员表面上有吸引力的东西,但是一旦这些抽象开始泄漏 - 就像抽象一样 - 你就完全在海上了解正在发生的事情.例如,SBElementArray声称是一个数组 - 它甚至是NSMutableArray的子类 - 但是当你真正尝试使用它的数组方法时,其中一半工作,而另一半则不工作.事实上,它根本不是一个真正的阵列; 它是一个未经评估的Apple事件对象说明符的包装器,假装它是一个NSMutableArray.因此,当它做一些非阵列式的事情时,你很大程度上是为了理解原因.而且,如#1中所述,这些厚抽象中的一些使得难以访问下面的标准Apple事件功能.
SB首先尝试成为一个优秀的Cocoa API,而不是一个优秀的Apple事件API,最终也不是很擅长.
顺便提一下,Appscript遵循AppleScript的主导并采取相反的方法:正确地做Apple活动,然后担心适应主机语言.这就是为什么有些人喜欢RubyOSA而不是rb-appscript; 虽然appscript是功能更强大的解决方案,但如果你来自面向对象的背景,它会感觉非常奇怪.这是因为Apple事件使用基于RPC-plus查询的范例,任何相似的应用程序脚本都可能需要OOP纯粹是语法.最接近的类比是通过XML-RPC发送XQueries,并且需要一些时间来习惯.
...
SB往往比AppleScript遭受更多的应用程序兼容性问题.
其中有些问题是由于SB强加了自己的苹果如何事件IPC的想法应该就它是如何工作的最高实际工作.例如,SB创建一组[伪]代理类,表示字典中定义的类; 然后,它主要基于经典的面向对象的行为规则,对如何与这些对象进行交互施加了各种限制.
例如,以下脚本获取Documents文件夹的所有子文件夹的名称:
tell application "Finder"
get name of every folder of entire contents of folder "Documents" of home
end tell
Run Code Online (Sandbox Code Playgroud)
如果您在SB中尝试相同的方法:
finder.home.folders.objectWithName('Documents').entireContents.folders.arrayByApplyingSelector(:name)
Run Code Online (Sandbox Code Playgroud)
它会到达#folders方法,然后抛出一个错误,因为Finder字典中'whole contents'属性的类型被声明为'reference'.由于没有在字典中定义"文件夹"元素的"引用"类,因此SB不允许您构造该特定查询(除非您想要下拉到低级API并使用原始AE代码).根据Apple事件规则,这是完全合法的,但不符合SB规定的较窄的以OO为中心的规则集.
其他错误是由于SB对可编写脚本的应用程序如何实现某些命令和其他功能做出了假设.例如:
tell application "iTunes"
make new playlist with properties {name:"test 1"}
end tell
Run Code Online (Sandbox Code Playgroud)
SB不允许您利用iTunes提供的任何快捷方式(您可以省略对您希望播放列表创建的源对象的引用,在这种情况下使用主"库"源),所以让我们写一下完整的比较:
tell application "iTunes"
make new playlist at source "Library" with properties {name:"test"}
end tell
Run Code Online (Sandbox Code Playgroud)
在SB中你写的是:
itunes = SBApplication.applicationWithBundleIdentifier('com.apple.itunes')
playlists = itunes.sources.objectAtIndex(0).playlists()
newplaylist = itunes.classForScriptingClass(:playlist).alloc().initWithProperties({:name => 'test'})
playlists.addObject(newplaylist)
Run Code Online (Sandbox Code Playgroud)
当你运行它时,它在#addObject上barfs.在尝试将单个'make'命令转换为多行练习时,SB假定'at'参数将始终是<object>'的<elements>结尾形式的引用,这就是Cocoa脚本的方式基于应用程序.Carbon应用程序没有一个用于实现Apple事件支持的标准框架,因此它们的要求往往会有所不同.例如,iTunes需要引用容器对象,在本例中为"source"Library"',并且当SB传递源"Library"的播放列表结尾时不喜欢它.这就是许多AppleScriptable应用程序的用途,但SB在其"面向对象"的决心中忽略了这一现实.
当应用程序字典不是100%准确或详尽无遗时,会引起更多问题.aete和sdef格式都不允许您描述应用程序的脚本界面如何以100%的细节工作; 有些事情必须由用户猜测,或在补充文档中描述 - Finder的"整个内容"属性的性质就是一个例子.其他信息,例如哪些类别的对象可以是其他类对象的元素,以及每个属性的类型,AppleScript本身从未实际使用过 - 它仅作为用户文档.由于AppleScript不依赖于这些信息,因此在测试应用程序对AppleScript的脚本支持时会遗漏任何错误,因为尽管脚本工作得很好.SB确实使用了这些信息,因此任何错别字都会导致丢失或损坏的功能,必须通过再次降低到低级API来规避.
Appscript,BTW,也不是100%'AppleScript兼容',但它确实非常接近.appscript的早期版本也试图强加给苹果事件,如执行字典定义的对象模型中的各种OO规则,但一年运行到应用程序不兼容后,我ganked所有的"聪明"的代码,并在接下来的几年努力黑盒逆向工程AppleScript的内部阴谋并使appscript尽可能地模仿它们."如果你不能打败他们(你不能),那就加入'em'吧.并在appscript不打的兼容性问题,通常有它周围的方式,包括翻转内部兼容性设置,然后导出应用术语的模块,由专人修补它,并使用替代,或下降到低级别的原料AE码蜜蜂.
...
FWIW,我还应该插一些相关的appscript好东西.
首先,appscript网站上的ASDictionary和ASTranslate工具是你的朋友.ASDictionary将以appscript风格的HTML格式导出应用程序字典,并在rb-appscript中启用内置的#help方法; 非常适合irb的互动开发.ASTranslate将采用AppleScript命令并且(错误愿意)在appscript语法中返回等效命令.
其次,rb-appscript的源代码分发包含文档和示例脚本.如果您安装了appscript gem,请记住抓取这些资源的zip分发版.
第三,Matt Neuburg写了一本关于rb-appscript的书.如果您正在考虑使用rb-appscript,请阅读它.无论你最终决定什么,去读库克博士的论文.
...
无论如何,希望有所帮助.(哦,并且道歉,但我本周刚刚写了大约25000个单词,所以这只是轻松一点.)
ps Ned,你闪亮的美元就在后面.;)
我还没有尝试过RubyOSA,但是我用rb-appscript取得了很大的成功.它对我来说非常有效,并且比直接使用AppleScript更好.
你看过这个线程比较两个吗?它有一个很好的详细答案,注意到差异.
归档时间: |
|
查看次数: |
6865 次 |
最近记录: |