OSXに最初からAppleScriptエディタという専用のエディタがインストールされています。コード補完や実行結果の表示など優れた機能を有していますのでこちらを使用することをおすすめ。アプリケーションフォルダのユーティリティの中にあります。
display dialog "hello world"
AppleScriptエディタのツールバーの実行ボタン(Command + R)でコンパイル&実行が行われます。正しい文法で記述されているかはコンパイルボタン(Command + K)で確認できます。
あとAppleScriptらしいhello worldはこんな感じで。
say "hello world"
AppleScriptは「オブジェクトに対してメッセージを送る」という考えでコードを書くのが基本。いわゆるオブジェクト指向言語というものです。アプリケーションはオブジェクトの一つと言えます。特徴的なのは比較的自然言語に近い形でコードが書けるところです。
tell referenceToObject to statement
例:iTunesにプレイリスト名"トップ 25"の再生を指示。
tell application "iTunes" to play the playlist named "トップ 25"
例:現在のアプリケーションに"hello world"ダイアログ表示を指示。
tell current application to display dialog "hello world"
tell current application to は省略可能。よく目にするコードはこの形。
display dialog "hello world"
これはAppleScriptエディタにダイアログ表示させるという指示です。これをiTunesにさせてみます。
tell application "iTunes" to display dialog "hello world"
するとiTunesがアクティブになりダイアログが表示されます。これはAppleScriptエディタではなくiTunesがダイアログを表示したという事です。本当にiTunesのダイアログなのかを確認するにはドックのiTunesアイコンからメニューを開きiTunesを隠してみてください。ダイアログも一緒に隠されます。iTunesを表示すると再びダイアログも表示されます。
このようにAppleScriptはオブジェクトに対して何らかの操作を指示することが簡単に出来る仕組みです。
このドキュメントはオブジェクトの操作を覚える前にまずAppleScriptの文法をごく簡単に学ぶことを目的として書いていますので、以下の対象とするオブジェクトはAppleScriptエディタとします。
単に結果を知るためだけならわざわざ表示させる必要はありません。エディタの下にある結果エリアに表示されます。編集エリアにて1 + 1と入力し実行してみてください。計算結果が表示されます。
何かを明示的に表示する場合はdisplay dialogコマンドを使います。
display dialog "hello (again)"
デバッグの為に値を表示したい場合はlogコマンドを使います。こちらは返された値かイベントのエリアで表示されます。
log "hello (again)"
hello worldでも挙げましたが、sayコマンドを使い指定した内容を読み上げさせることもできます。
say "think different."
一行コメント
-- this is comment.
ブロックコメント
(*
これはブロックコメントです。
複数行のコメントはこちらを使用します。
*)
変数は前もって宣言する必要はありません。値を代入する記述を行えばすぐに変数を使用できます。型は特に指定する必要はありませんが明示することも可能です。
値を変数に代入するにはsetコマンドを使用します。
-- 変数oneに数値の1を代入
set one to 1
-- 変数fooに文字列"foo"を代入
set foo to "foo"
-- 変数barに真を代入
set bar to true
-- 変数bazに文字列"baz"を文字列であることを明示して代入。
set baz to "baz" as text
copyコマンドで変数に値を代入するも出来ます。
copy 1 to one
getコマンドで変数から値を取得します。getを省略し単に変数名だけでも値を取得できます。
set foo to "foo"
get foo
--> "foo"
a reference toコマンドは左辺の値を求めるのではなく右辺の参照として処理します。
set one to 1
set ichi to a reference to one
get ichi -- get oneと同義
ichi + ichi
--> 2
missing valueを代入することが出来ます。missing valueは初期化されていない値を意味します。
set foo to missing value
get foo
--> missing value
localコマンドでスコープ内に有効な変数の宣言、globalコマンドで全てのスコープに対して有効な変数の宣言ができます。
local foo -- defines one variable
local bar,baz -- defines 2 variables
global hoge
global fuga, hogera
数値を表すnumber、整数のinteger、実数のrealの3つが型として使用できます。
set a to 1
set b to 1.234
set b to b as integer
--> 1
set a to a as real
--> 1.0
set a to "100"
set b to a as number
--> 100
-- 加算
1 + 1
--> 2
-- 減算
1 - 1
--> 0
-- 乗算
1 * 1
--> 1
-- 除算
10 / 3
--> 3.333333333333
-- 商
10 div 3
--> 3
-- 余り
10 mod 3
--> 1
インクリメント、デクリメントはありません。
文字列はダブルクォートで囲みます。enterキーで文字列を改行させることができます。タブやリターン、改行などの特殊記号は\t、\r、\nと書きます。
set str to "this is test."
set str to "
this
is
test.
"
set str to "\tthis is \ntest.\r"
注意:AppleScriptエディタの環境設定で特殊文字を展開する場合があります。
-- 結合
"aaa" & "bbb"
--> "aaabbb"
-- 分割
set AppleScript's text item delimiters to {","}
text items of "aaa,bbb,ccc"
–-> {”aaa”, ”bbb”, “ccc”}
-- 長さ
length of "あいうえお"
–-> 5
count "あいうえお"
--> 5
-- 切り出し
–- 1~3文字目
text 1 thru 3 of "ABCDEFG"
–-> “ABC”
–- 4~末尾
text 4 thru -1 of "ABCDEFG"
–-> “DEFG”
–- 4~末尾の1つ前
text 4 thru -2 of "ABCDEFG"
–-> “DEF”
-- delimitersの使用例
set tempDelimiters to AppleScript's text item delimiters
set filePath to "Macintosh HD:Users:hoge:Desktop:example.applescript"
set AppleScript's text item delimiters to {":"}
get text items of filePath
--> {"Macintosh HD","Users","hoge","Desktop","example.applescript"}
get first text item of filePath
--> "Macintosh HD"
get last text item of filePath
--> "example.applescript"
get text item 3 of filePath
--> "hoge"
repeat with anItem in text items of filePath
log anItem
end repeat
(*
--> "Macintosh HD"
"Users"
"hoge"
"Desktop"
"example.applescript"
*)
copy tempDelimiters to AppleScript's text item delimiters
AppleScriptには標準の検索・置換機能はありません。delimitersを使用して独自に検索機能を書く必要があります。操作対象のアプリケーションによっては検索・置換コマンドが用意されているのでそちらを使うのが簡単です。
AppleScriptで配列はリストと呼びます。
-- リスト
{"foo", "bar", "baz"}
-- リストの入れ子
{{1, 2, 3}, {2, 3, 4}, {3, 4, 5}}
-- リストの連結
{"foo"} & {"bar", "baz"}
--> {"foo", "bar", "baz"}
-- 要素数
count {"foo", "bar", "baz"}
--> 3
-- 要素数 整数のみ
count integers in {"foo", "bar", "baz", 1, 2, 3}
-- 3番目の要素
item 3 of {"foo", "bar", "baz"}
--> "baz"
-- ランダムな要素
some item of {"foo", "bar", "baz"}
-- 4〜6の要素
items 4 thru 6 of {"foo", "bar", "baz", 1, 2, 3}
--> {1, 2, 3}
-- 要素の並びを反転
reverse of {"foo", "bar", "baz"}
--> {"baz", "bar", "foo"}
-- 先頭を除いた残りの要素
rest of {"foo", "bar", "baz"}
--> {"bar", "baz"}
リストの操作は直接影響を及ぼしません。実際に内容を変更したい場合はsetやcopyを用いて代入する必要があります。
AppleScriptの連想配列はレコードと呼ばれます。
-- レコード
{name:"Steve", height:74.5, weight:170}
-- キーがnameの要素
name of {name:"Steve", height:74.5, weight:170}
-- 連結
{name:"Steve", height:74.5, weight:170} & {lastName:"Jobs"}
-- 要素数
count {name:"Steve", height:74.5, weight:170}
-- 要素数 値が文字列のみ
count text in {name:"Steve", height:74.5, weight:170}
-- ランダムな要素
some item of {name:"Steve", height:74.5, weight:170}
レコードの操作は直接影響を及ぼしません。実際に内容を変更したい場合はsetやcopyを用いて代入する必要があります。
-- 要素への代入
copy 210 to weight of {name:"Steve", height:74.5, weight:170}
-- 要素の追加
set aRecord to {name:"Steve", height:74.5, weight:170}
copy aRecord & {lastName:"Woz"} to aRecord
レコードから任意の要素を削除するコマンドはありません。新たにレコードを構築し直して代入する必要があります。
制御文は他の言語に比べて貧弱かもしれません。条件分岐でswitchに相当するものはなくif文のみ。繰り返しもrepeatだけです。
if 条件式 then
else if 条件式 then
else
end if
-- 指定した回数の処理を行う
repeat 繰り返す回数 times
end repeat
-- 指定範囲内で処理を繰り返す
repeat with 変数 from 開始 to 終了
end repeat
-- リストを順に繰り返し
repeat with 変数 in リスト
end repeat
-- 条件一致まで繰り返す
repeat while 条件式
end repeat
-- 無限ループ
repeat
end repeat
-- ループから抜ける
repeat
if 条件式 then exit repeat
end repeat
演算子の一覧です。AppleScriptは自然言語に近い記述ができるよう表現方法が豊富です。しかし最初からそれを全て覚えて書くのは大変。ここでは自分がよく使うものだけをピックアップしました。詳しくはオフィシャルドキュメントを参照してください。
AppleScript Language Guide - Operators Reference
AppleScript operator | 説明 |
---|---|
=, is | 等しい |
is not | 等しくない |
and | かつ |
or | または |
> | より大きい |
< | より小さい |
>= | 以上 |
<= | 以下 |
-- 基本形
try
on error
end try
-- エラーハンドリングの例
try
error number -10004 -- エラー番号-10004のエラーを発生
on error message number n
if n = -128 then (*ユーザによってキャンセルされました。*)
-- do something
else if n = -10004 then (*アクセス権の違反が起きました。*)
-- do something
else -- 想定外のエラーは再度エラーとする
log message
error number n
end if
end try
AppleScriptではサブルーチンをハンドラと言います。
-- 基本
on helloWorld()
display dialog "Hello World"
end
helloWorld()
-- 位置パラメーター形式のハンドラ
on greeting(message)
display dialog message
end
greeting("hello, again")
-- ラベル付きパラメーター形式のハンドラ
to findNumbers of numberList above minLimit given rounding:roundBoolean
set resultList to {}
repeat with i from 1 to (count items of numberList)
set x to item i of numberList
if roundBoolean then -- round the number
-- Use copy so original list isn’t modified.
copy (round x) to x
end if
if x > minLimit then
set end of resultList to x
end if
end repeat
return resultList
end findNumbers
set myList to {2, 5, 19.75, 99, 1}
findNumbers of myList above 19 given rounding:true
--> {20, 99}
-- 定義済みラベル付きパラメーター形式のハンドラ
on rock around the clock
display dialog (clock as text)
end rock
rock around the current date -- 現在日時を表示
ハンドラのパラメーターにはいくつかの種類がありますが、これはハンドラを使用する際の記述の可読性を高める目的で使い分けます。すべてを位置パラメーター形式で定義してもかまいません。またonの代わりにtoを用いて定義することも可能です。やはりこちらも可読性を高めるのが目的でどちらを使用しても機能的な差異はありません。
AppleScriptはプロトタイプベースのオブジェクト指向言語です。オブジェクトの定義がそのままインスタンスとなり即利用できます。AppleScriptで定義できるオブジェクトはスクリプトオブジェクトといいます。スクリプトオブジェクトにはプロパティとハンドラを定義できますが、その他にコマンドやハンドラの呼び出しを列挙できます。継承はparentプロパティを使い簡単に行えます。
-- 基本形
script John
property HowManyTimes : 0
to sayHello to someone
set HowManyTimes to HowManyTimes + 1
return "Hello " & someone
end sayHello
end script
tell John to sayHello to "Herb" --result: "Hello Herb"
tell John
sayHello to "Rose"
sayHello to "Grace"
end tell
-- ハンドラによるスクリプトオブジェクトの初期化と生成
on makePoint(x, y)
script thePoint
property xCoordinate:x
property yCoordinate:y
end script
return thePoint
end makePoint
set aPoint to makePoint(0,0)
get xCoordinate of aPoint --result: 0
get yCoordinate of aPoint --result: 0
set myPoint to makePoint(10,20)
get xCoordinate of myPoint --result: 10
get yCoordinate of myPoint --result: 20
get xCoordinate of aPoint --result: 0
get yCoordinate of aPoint --result: 0
tell myPoint
set xCoordinate to 20
set yCoordinate to 40
get xCoordinate --result: 20
get yCoordinate --result: 40
end tell
-- 継承
script Alex
on sayHello()
return "Hello, " & getName()
end sayHello
on getName()
return "Alex"
end getName
end script
script AlexJunior
property parent : Alex
on getName()
return "Alex Jr"
end getName
end script
-- Sample calls to handlers in the script objects:
tell Alex to sayHello() --result: "Hello, Alex"
tell AlexJunior to sayHello() --result: "Hello, Alex Jr."
tell Alex to getName() --result: "Alex"
tell AlexJunior to getName() --result: "Alex Jr"
script John
property vegetable : "Spinach"
end script
script JohnSon
property parent : John
end script
set vegetable of John to "Swiss chard"
vegetable of JohnSon
--result: "Swiss chard"
-- オーバーライドしたハンドラから親ハンドラを呼ぶcontinueの例
script Elizabeth
property HowManyTimes : 0
to sayHello to someone
set HowManyTimes to HowManyTimes + 1
return "Hello " & someone
end sayHello
end script
script ChildOfElizabeth
property parent : Elizabeth
on sayHello to someone
if my HowManyTimes > 3 then
return "No, I'm tired of saying hello."
else
continue sayHello to someone
end if
end sayHello
end script
tell Elizabeth to sayHello to "Matt"
--result: "Hello Matt", no matter how often the tell is executed
tell ChildOfElizabeth to sayHello to "Bob"
--result: "Hello Bob", the first four times the tell is executed;
-- after the fourth time: "No, I’m tired of saying hello."
スコープの区切りはスクリプトオブジェクトとハンドラになります。最上位のスコープをトップレベルと呼びます。暗黙でスクリプト自身はトップレベルのスクリプトオブジェクトです。トップレベル直下のハンドラはスクリプト自身のメンバという位置づけです。
set a to 0
if true then
set a to 1
end if
get a
--> 1
on foo()
set a to 2
get a
--> 2
end foo
foo()
get a
--> 1
script bar
set a to 3
get a
--> 3
end script
run bar
get a
--> 1
トップレベルの変数とプロパティは操作対象のアプリケーションが終了するまで値を保持します。なのでアプリケーションが起動している間にスクリプトを再び実行すると前回の値が残った状態で実行することになります。トップレベルでないスクリプトオブジェクトと変数のライフサイクルはハンドラの終了で寿命を終えます。
try
log a
on error
set a to 0
log "error " & a
end try
set a to a + 1
on foo()
try
log a
on error
set a to 0
log "foo ():error " & a
end try
set a to a + 1
end foo
foo()
script bar
try
log a
on error
set a to 0
log "bar:error " & a
end try
set a to a + 1
end script
run bar
-- ファイルの書き込み
set filePath to "Macintosh HD:Users:hoge:TheFile"
set fp to open for access file filePath with write permission
try
write "Some text. And some more text." to fp
on error msg number n
close access fp
error msg number n
end try
close access fp
-- ファイルの読み込み
set aFile to "Macintosh HD:Users:hoge:TheFile" as alias
set fp to open for access aFile
try
set myText to read fp
on error msg number n
close access fp
error msg number n
end try
close access fp
-- ファイルの読み込み その2
set myText to read ("Macintosh HD:Users:hoge:TheFile" as alias)
open for access fileでファイルを開きます。with write permissionで書き込み用として開きます。オープンに失敗するとスクリプトは停止します。書き込み時に発生するエラーの対応として開いたファイルを必ず閉じる必要があるのでエラーハンドリングしてファイルを閉じます。
ファイル入出力に関しての説明がコマンドの使い方の説明になっているので書き直す必要あり。また文字コードの扱いに難が有る為、実質的に使えない。