AppleScript の新機能 (4) - use 構文

正直...よく分からない use 構文について。

このページを見るとその効用と使い方が説明されているんですけどね。でも、今のところ必要ないかな。というか、使えない?

それとも、使い方を間違えているかな?

最初に説明を読んだときは、AppleScript Editor の環境設定にある「"tell application" ポップアップメニュー」の代替になるものだと思っていました。でも、そうではなかったのです...。

use 構文の機能は色々とあるのですが、主要なところは以下の3つ。

  • tell 構文の代替
  • ライブラリスクリプトのインポート
  • Cocoa フレームワークのインポート

それぞれみていきますが、それぞれに「?」と思うような挙動があります。

tell 構文の置き換え

use 構文でアプリケーションを指定することができます。指定することで、そのアプリケーションが持っている命令やプロパティを取り込むことができます。

AppleScript ってタイプ量が多く、スクリプトが横に横に長くなってしまいがちです。use 構文が使えるなら、タイプ長もスクリプトの見通しもかなり改善されるはずなのです。

例えば、Finder で選択しているファイルを取得するために以下のようなことをしてみます。

Script Editor で開く

use application id "com.apple.finder"

selection

AppleScript Editor 上で実行すると、AppleScript Editor で選択しているテキストを返します。おお。予想をかなり裏切っているんだけど...。

つまり、use 構文って、current application(命令等が送られる対象)を指定するものでは『ない』のですね。だから、上記のスクリプトを AppleScript Editor 上で実行すると current application である AppleScript Editor に命令が送られ、その結果が返ってくる、と。

しかし、指定したアプリケーションの用語辞書は取り込んではいる。なので同じ命令や属性を持っているアプリケーションでは用語の衝突が起きたりもします。例えば、次のスクリプトだとエラー(というか、構文確認が通らない)になります。

Script Editor で開く

use application "Finder"
use application "System Events"

disks

これを回避する方法が...ないんですね。困ったものです。一応、以下のようにするといいんですけど。

Script Editor で開く

use application "Finder"
use application "System Events"

tell application "Finder"
    disks
end tell

って、今までと一緒かーい。

と、単純に tell application "appname" が不要になるかと思えば、そう簡単でもないというお話でした。

ライブラリの指定

Script Libraries のスクリプトを指定して、その中で定義されているハンドラをインポートすることができます。

おそらく、use 構文はこのためだけに利用するのが一番もっともらしい使い方なのかも知れません。ただし、『そのスクリプトで用語辞書を定義している』なら。

Script Libraries は単純に自分で定義したハンドラ群を放り込んでおいて利用する(つまり、従来の load script 命令の代替として)だけなら便利なものなのですが、use 構文が絡むと上記の tell のときと同じように使いにくいものになります。

use script "TextUtility"

tell application "Finder"
    set theFile to file 1 of desktop
    set filename to displayed name of theFile
    toUpper(filename) -- script "TextUtility" で定義しているハンドラ
end tell

このように自分で作ったハンドラを tell 構文の中で呼び出そうとしてもエラーになるだけです。use 構文があるから使えそうなものですが、用語辞書を定義していないのでハンドラ未定義のエラーになります。誰のものかを指定する必要があります。

use script "TextUtility"

tell application "Finder"
    set theFile to file 1 of desktop
    set filename to displayed name of theFile
    toUpper(filename) of script "TextUtility" -- 誰のハンドラかを指定する
end tell

つまり、こういった用途では use 構文の出番はありません。

-- use script "TextUtility" -- 不必要なのでコメントアウト

tell application "Finder"
    set theFile to file 1 of desktop
    set filename to displayed name of theFile
    toUpper(filename) of script "TextUtility" -- 誰のハンドラかを指定する
end tell

単純にこれだけで事足ります。もし、use 構文を使ってライブラリにあるスクリプトを取り込むのなら、用語辞書が必須です。

フレームワークの指定

最も分からないのが、これです。

Script Libraries のスクリプトには Objective-C を利用できます。そのために必要な Cocoa フレームワークの取り込みに利用できる...と書かれているんですが、use 構文を使わなくても Cocoa フレームワークを取り込んでいたりします。

次のスクリプトは「連絡先」アプリケーションに登録されている人を、電話番号で検索するもの。

Script Editor で開く

on findPeople(phoneNumber)
    (*
    電話番号文字列で検索
    *)
    set str to current application's NSString's stringWithString:phoneNumber
    set ab to current application's ABAddressBook's sharedAddressBook()
    set searchElement to current application's ABPerson's searchElementForProperty:(current application's kABPhoneProperty) label:(missing value) |key|:(missing value) value:str comparison:(current application's kABContainsSubString)
    set personFound to ab's recordsMatchingSearchElement:(searchElement)

    repeat with thisItem in personFound
        set lname to (thisItem's valueForProperty:(current application's kABLastNameProperty))
        set fname to (thisItem's valueForProperty:(current application's kABFirstNameProperty))
        log {lname as text, fname as text}
    end repeat
end findPeople

まぁ、わざわざ Cocoa フレームワークを利用しなくてもいいのですが、これは動きます。use 構文でフレームワークを指定していないにも関わらず。

いやいや。怒ってくるよ。

import "ABAddressBook.h"

なんてしている人が。なに、なんちゃってスクリプトでまともに動いてんだよ、って。

利用しているのがクラスメソッドだから?

WebKit なんかの init 関係のメソッドは use 構文で フレームワークを指定していないとエラーになります。でも、QuartzCore の CIImage ではエラーにならない。

ワケが分からない。法則性がない。

その他の機能

use 構文では、これらの他に読み込むアプリケーションのバージョン指定や、利用する AppleScript のバージョン指定、指定したアプリケーションの用語辞書を読み込むかどうかの指定ができたりもします。

アプリケーションのバージョンの指定って微妙。通常なら、対象アプリケーションのバージョンを調べてからスクリプトを実行するでしょう。バージョンの指定ができたからって調べる手間が省けるわけでもなく、利用するスクリプトを変更することもできない。しかも、バージョン指定はそれまでの全てのバージョンを含んでしまいます。

バージョン 5 を を指定するとバージョン 1 も 2 も 3 も 4 も含みます。1 から 4 は必要なく、5 だけを指定ってできない。微妙...ですよね?

結論

今のところ、積極的に利用する利便性がない。今後...なのでしょうが、どうもねぇ...。

0 件のコメント :

コメントを投稿