タスク管理パートナーのロボサトウ(仮)君。自動化は便利だけど矛盾もある。だけど「タノシイ」はだいじ。着色バージョンは次の記事に。

OS Xをスクリプトで行う自動操作は、AppleScriptで制御する場合はそのまま「AppleScript」、JavaScriptの場合は「JavaScript for Automation(以下JXA)」と呼ばれています。ちょっとややこしいけど、慣れるしかないでしょう。

僕は元々AppleScript自体がほとんど分からない状態だったけど、どうやらAppleはOSXのスクリプティングをAppleScriptからJavaScriptに置き換えたいらしいです。

AppleScriptは全然だけど、JavaScriptならチャンスか?
気が向いたのでJXAを触ってみる事にしました。ただ、情報が今ひとつ探しにくく、自分なりに扱える様になったと実感するまで、けっこう苦労しました。

……という訳で今回は僕がJXAの学習がてら、「最初にこの情報が欲しかった」と思える要素をまとめてみます。

AppleScriptに対するJXAの利点

そもそも、なぜ元々長く使われているAppleScriptがあるのに、わざわざJavaScriptもMacを動作させる事が出来るようになっているの? そのメリットは? ですね。

まず、AppleScriptよりも広く使われているJavaScriptで書ける事自体が一番のメリットでしょう。
特にAppleScriptには無くて、JavaScriptにある機能を利用できる事はかなり大きいです。

たとえば、AppleScriptは標準では正規表現が使えないけど、これをJavaScriptで書けば標準でRegExpオブジェクトが使えるので、かんたんに正規表現が使えちゃいます。

下記のJXAスクリプトの様な機能をAppleScriptで書こうとすると、結構煩雑なコードになるはずなんだけど、JXAならこれくらいの記述で済んじゃいます。

// Chromeで開いている、他人に見られちゃまずいページのタブを一気に閉じる

// まずいURLの正規表現オブジェクト達
var dangerUrlRegExps = [
  /dmm\.co\.jp.*/,
  /duga\.jp.*/,
  /mgstage\.com.*/
];
var chrome  = Application("Google Chrome");
var windows = chrome.windows;
var closeTabs = []; // 閉じるタブを入れる配列

// 全ウィンドウとタブを走査し、
// URLが正規表現にマッチするタブをcloseTabsに入れる
for ( var i in windows ) {
  var tabs = windows[i].tabs;
  for ( var j in tabs ) {
    for ( var k in dangerUrlRegExps ) {
      if ( tabs[j].url().match(dangerUrlRegExps[k])) {
        closeTabs.push(j);
      }
    }
  }
}

closeTabs.forEach(function(ct) { // Arrayオブジェクトの便利メソッドも使える
  chrome.delete(tabs[ct]);
});

ボリュームのあるプログラムを書こうとすればするほどJSXのメリットは大きくなりそうですね。

SafariのWebインスペクタのデバッガが使える

デバッガはOSX 10.11から利用できるようになった機能で、SafariのWebインスペクタを利用します。

Safariを立ち上げ、「開発 > (Macの名前) > JSContexts の Web インスペクタを自動的に表示」にチェックを入れる。

これを活用しながらだと大分快適に書けるはずです。 Safariを立ち上げたままにしておき、スクリプト中に「debugger」と書いてから実行すると、そこからSafariのWebインスペクタが立ち上がり、デバッガで動きを追うことができます。

ブラウザで動かすJavaScript同様に、普通に普通にブレークポイントやウォッチ式で動きをチェックできる。すごい新鮮な感覚でおもしろい。

AppleScriptで書く場合はlogコマンド等を駆使するのが基本みたいなので、これは大きなアドバンテージですね。

AppleScriptの利点は情報量とStandardAdditionsの手軽さ?

対して、JXAに対するAppleScriptの第一の利点は、やっぱりこれまで使われてきた歴史があるので、探せば大体の情報、コードが見つかります。

JXAの事を調べようにも、情報が少ないので、AppleScriptで調べて見つけたコードをJXAに書き換えて使う、本末転倒っぽい事も(笑)

メリットともデメリットとも言えそうなのは、StandardAdditionsの使い勝手です。

StandardAdditionsはOSXの標準機能に関する命令の集まった物です。 コピー&ペーストや、ダイヤログなど、Macにインストールされるアプリケーションの多くから、共通して利用できるOSの機能が詰まっています。

ライブラリの「StandardAdditions」に含まれている機能はJXAでは標準では使えない。Applicationクラスの「includeStandardAdditions」をtrueにすることではじめて使える。

便利で汎用性が高いStandardAdditionsだけど、これらの機能をJXAから扱うには、コードに下記の様な記述を追加する必要があるけど、AppleScriptで書くなら、それが必要無いです。

app.includeStandardAdditions = true;

大したこと無い手間かもしれないけど、ちょっと実験的に数行のJXAのスクリプトを書こうとする度に、いちいちこれを追加するのは面倒に感じます。

強力なStandardAdditionsの機能をJXAに安全に使うためのメリットであるとも言えるのかなとは思うけど、ダイヤログひとつ表示させるのにこんなに手間が掛かるのはなんとも(笑)

AppleScriptなら、こんな感じでささっと書けるのに……

display dialog "メッセージ"

JXAならこれだけ書いてやっとダイヤログを表示できるなんて、面倒で仕方ないです。

var app = Application.currentApplication();
app.includeStandardAdditions = true; // これ書くのめんどくさい
app.displayDialog('メッセージ');

ごくシンプルな動作はAppleScriptなら言葉も直感的で分かりやすく、記述量も少なくて済むけど、複雑な処理をさせようとするほど、逆にJXAの方が楽に書けるメリットが大きくなる感じなんだと思います。

あと、AppleScriptで書く場合は、スクリプトエディタ.appの「記録」が使えるメリットも一応あるけど、実際はごく簡単なファイル操作以外の記録出来ない事が多かったりと、僕の用途では大きなメリットが見出せてないです。

JXAの日本語情報あつめ

とりあえず調べ物をするときは「JavaScript for Automation」または「JXA」の語句と一緒に検索する事で、ある程度はみつかるけど、やっぱり情報は少なめです。
JXAだけで検索するより、AppleScriptで検索して、それをJSに書き換えてしまう方が簡単なシーンも結構あるはずです。 なんで僕はJXA書こうとしてるんだ?

以下のサイトはそんな探し方をしてると頻出してお世話になった、JXAの日本語記事たちです。

JavaScript自動化 - mytrans マニュアル等の個人的な翻訳
英語のみの公式ドキュメントが神によって翻訳されたもの。
元ドキュメント自体が不親切なので、これだけで理解するのは厳しいけど、大分助けになるはずです。
鳶嶋工房 / AppleScript / JavaScript for Automation (JXA)
JXAの基本が公式よりも分かりやすくコンパクトにまとまっている記事。たぶん一番お世話になりました。
Mac : JavaScript for Automation (JXA) 例文辞典
数多くの技術書を執筆されている古籏 一浩さん[OpenSpace]によるサンプルコード。
実際にサンプルコードを動かすのが一番手っ取り早く理解するのに良いかなと。
zakuroishikuro - Qiita
日本語のJXA情報を検索すると、この方の記事が本当に良く出てきて、実例も盛り沢山です。特に「Google先生も知らないJXAのプライベートメソッド」の記事で紹介されていたproperties()はJXAを触り始めた瞬間から役立つ便利な機能。

英語だけど、見逃す事はできないJXA情報

Introduction to JavaScript for Automation Release Notes
AppleのJXA公式ドキュメント。英語のみ……。あんまり親切に解説してる様にも見えない。
JavaScript for Automation Cookbook
JXAを今がっつり書くには、どうしてもAppleScriptの知識が不可欠なんだけど、それをある程度補完してくれる、具体的なサンプルコード多くてイメージが大分掴めます。

そんな感じで、意外に情報の少ないJXAの入門情報のまとめでした。
次回はそこから一歩進み、僕にとってはかなりハードルの高かった「スクリプトエディタ.app」のライブラリを読み解きながら実際に実用的なスクリプトを書いてみます。