箕原辰夫(Copyright by Tatsuo Minohara, 2007-2008)
変数を用いる内容をAppleScriptを使って記述してみましょう。まず、変数は作る必要はありません。 AppleScriptが未知の名前が出てくれば、そのまま変数として解釈してくれます。 何が未知で使って良い名前なのかを知るのは難しいのですが、 だいたい変数名はcountNumberなどと、小文字で始まり、複合語にするのが無難な命名の仕方になっています。
プロンプトへの表示は、display dialogですが、整数などは自動的に文字列に変換してくれます。 また、display dialogは、default answerというオプション(Option:つけてもつけなくても良い記述のこと) の後に文字列を記入しておけば、文字列入力用のダイアログになります。 その入力結果がresult(結果)という名前の変数に入ります。この結果には、どのボタンが押されたとか、 入力された文字列はどんなものだったか、いくつかの情報が入っていますので、入力文字列を取り出すには、 text returned of というプロパティ(Property:オブジェクトの持つ付属情報のこと)を使って取り出して あげます。
どうしても、明示的に別のクラスにしないといけないときは、たとえば文字列に変換するものとして (<式> as string)や、整数に変換するものとして(<式> as integer)が用意されています。 取り出した結果は文字列のままなので、as integerで、整数に変換してしてあげます。
代入文は、「set <変数名> to <式>」という形です。掛け算マークは、アスタリスクが標準です。 ここまでわかったところで、AppleScriptでの記述がどうなるか、先ほどのプログラムを書き直してみましょう。 変数名は、もちろんtakoChanです。
display dialog "Input Number" default answer "1234" set takoChan to (text returned of result) as integer display dialog (takoChan * takoChan)
AppleScriptも内容的にはこの節でやったことはほとんど同じです。演算子などの記号はすべて 半角になります。半角の「+」と「-」、「*」および「/」をそれぞれ加算・減算・乗算・除算に使って下さい。 AppleScriptでも、英語モードでOption+/で変換できる「÷」が使えますが、コンパイラは強制的に「/」に置き換えてくれます。 1つ違うのは、除算は割り切れないときは、自動的に実数にしてしまうことです。 以下のようなプログラムを実行してみてください。割り切れない整数を入力したら、実数として答えが表示されます。
display dialog "Input Number" default answer "1234" set takoChan to (text returned of result) as integer display dialog (takoChan / 3)
整数除算と整数剰余はどこに行ったの?と思う人がいるかも知れませんがご安心ください。 AppleScriptでは、整数除算は「div」、整数剰余は「mod」という英語の名前で記述する演算子が用意されています。 ちなみにmodは、「modulus」の略だと思います。 ですから、「/」と「div」では評価結果が異なる場合があると思ってください。下のプログラムでは、3で割ったときの 整数除算と整数剰余も表示するようにしました。 なお、AppleScriptでは文字列同士の結合や、文字列と数値の結合ができます。 この結合演算子は、「&」(半角のアンパサンド)です。 演算結果は文字列になりますので、display dialogで表示できます。
display dialog "Input Number" default answer "1234" set takoChan to (text returned of result) as integer display dialog "Original Number: " & takoChan & " and a real third of it " & (takoChan / 3) display dialog "a integer third of it " & (takoChan div 3) & " and its reminder is " & (takoChan mod 3)
なお、上記の表のように整数剰余と整数除算、m div n * nの値を繰り返し表示するようなプログラムを 作成してみました。終了させるには、切りがいいところで「キャンセル」ボタンを押してください。 display dialog のところ入りきらないので3行に分かれていますが、1行で書いて下さい。 スクリプトエディタは自動的に折り返してくれます。display dialogの最初の""は、文字列の結合のために 必要になります。また、returnは、改行コードを意味しています。
display dialog "Input Divider" default answer "3" set divider to (text returned of result) as integer set aNumber to 0 repeat display dialog "" & aNumber & " mod " & divider & " is " & (aNumber mod divider) & return & aNumber & " div " & divider & " is " & (aNumber div divider) & return & aNumber & " div " & divider & " * " & divider & " is " & (aNumber div divider * divider ) set aNumber to aNumber + 1 end
ファイルメニューの用語説明を開くで、Standard Additionsを選んでみて下さい。 Miscellaneous Commandsと書かれたSuite(コマンドやクラスのグループのことです)の中に、 random numberというコマンドがあります。
random number あるいは
random number from <最小値> to <最大値>
random numberだけを使うと、0.0から1.0(1.0も含む)までの乱数を返してくれます。 また、2つ目の書式で、最小値や最大値に整数を使うと、整数の乱数を返してくれます。 次の例は、1から50までの整数の乱数を発生させ、theNumberという変数に代入しています。
set theNumber to random number from 1 to 50
上記の3つの仮定文は、一般にはif文と呼ばれていて、多くの言語で使われています。もちろん、 AppleScriptでもそろっています。AppleScriptの場合は、ifとthenおよび、elseを使います。 言霊でも説明したように、第3番目の仮定文は、第1番目と第2番目の書式を包括していますので、 文法規則の書式は以下のように第3番目のif文の書式で記述します。以下の規則で[]は省略可能で、 …は、何回繰り返しても良いことを示しています。AppleScriptでは、制御文は改行されていることが 結構重要なので、thenやelseの後で改行していない場合は、コンパイラは通りません。
if <条件式> then
文…
[else if <条件式> then
文…]…
[else
文…]
end
以下のプログラムは、Excelでやったグレード評価を単体の値に対して行なったものです。 ユーザから入力された値に対してグレード評価を表示する単純なものです。
display dialog "Please your point of the exam" default answer "82" set thePoint to (text returned of result) as integer if thePoint ≥ 80 then set theGrade to "A" else if thePoint ≥ 60 then set theGrade to "B" else if thePoint ≥ 40 then set theGrade to "C" else set theGrade to "D" end display dialog "Your grade is " & theGrade
ところで、上記のサンプルの比較演算子の記号がちょっと違うのに注意してください。 AppleScriptのスクリプトエディタでは英語モードで入力するので、 ナナエディタと同様に「≠」がOption+^で入力することができる以外に、 「≤」と「≥」については、Option+<と、Option+>で入力します。 ちなみに、AppleScriptの比較演算子は、AppleScript自体が英語の自然言語で書けることを目指していることも あり、豊富に用意されています。単なる記号以外に、英文のフレーズが使えます。このフレーズが多過ぎのような気も するのですが、自然言語風に書けるためには、ここまで用意しなければならないのかなぁと思ってしまいます。 ちょっと以下の表を見てみてください。[ ]は省略可能で、|は「いずれか」を意味しています。
Operators for Comparison 意味 使用例
> | [is] greater than | comes after |
is not less than or eual [to] | isn't less than or equal [to]左の式が右の式より大きい takoChan > 10 < | [is] less than | comes before |
is not greater than or euqal [to] | isn't less than or equal [to]左の式が右の式より小さい x is less than y + 10 ≥ | >= | [is] greater than or equal [to] |
is not less than | isn't less than |
does not come before | doesn't come before左の式が右の式より大きいか等しい x >= 10 ≤ | <= | [is] less than or equal [to] |
is not greater than | isn't greater than |
does not come after | doesn't come after左の式が右の式より小さいか等しい x doesn't come after y = | is | equal | equals | [is] equal to 左の式が右の式と等しい x equals y ≠ | is not | isn't | isn't equal [to] |
is not equal [to] | doesn't equal | does not equal左の式が右の式と等しくない x≠0
AppleScriptの論理演算子not and orの方がより一般のプログラミング言語に近いと考えることができます。 演算子の優先順位もnot and orの順でnotが一番高く、orが一番低くなっていきます。 次のプログラムは西暦を昭和に変更するものです、and用いられているのがわかります。
display dialog "西暦(1925〜1989)を入れて下さい" default answer "1950" set theYear to (text returned of result) as integer if theYear ≥ 1925 and theYear ≤ 1989 then display dialog "西暦" & theYear & "年は昭和" & (theYear-1925) & "年です。" else display dialog "入力値が間違っています。" end
回数繰返し文は非常に直感的にわかりやすくて素晴らしい制御文です。他の言語でこれを持っているのは、 AppleScriptぐらいしか知りません。ちなみにAppleScriptでは、以下のように記述します。 プログラミング例を挙げておきますが、文法的には「repeat <回数を示す整数式> times」の部分です。 また、「display dialog」は、ダイアログを出して文字列を表示するような命令文です。
repeat 3 times display dialog "Hello Macintosh" end
時間に余裕があれば、アプリケーション >> AppleScript >> スクリプトエディタを起ち上げて、 上記のプログラムを入力して、コンパイルボタンでコンパイルし、実行してみて下さい。なお、スクリプトエディタ では、入力したプログラムを保存しなくても実行できます。 なお、AppleScriptは英語ですから、⌘+Spaceで言語スクリプトを切り替えて、英字入力にして 全部半角英字で入力して下さい。
AppleScriptでは、繰返しのネストは次のように記述されます。sayというのは、 指定した文字列をMacintoshの音声発音システムに発声させるためのコマンドです。
repeat 3 times repeat 2 times display dialog "Hello Macintosh" end say "Thank you for your boring tasks" end
AppleScriptでも永遠繰返し文が存在します。終了させるには、スクリプトエディタのウィンドウで「中止」 ボタンを押すか、display dialogで出されたダイアログの中で「キャンセル」ボタンを押します。
repeat display dialog "Eternal Loop, please press cancel button for stop" end
AppleScriptでも、条件式を用いた繰返しがあります。 それ以外にも後で説明するループ変数を指定した、一般にfor文と呼ばれる繰返し文や、 更に強力な繰返し文(Javaも5.0から採用されたforeach文と呼ばれるもの)もあるのですが、 それはJavaの説明のときにでも触れることにします。 ここでは、条件式を用いた繰返しの文法規則と簡単な例のみをご紹介します。
repeat while <条件式>
-- 繰返すこと
end
以下のプログラムは、インチをcmに変換するものですが、現行のMacintoshの機種に関しては、何かしらの 表示が追加されます。お手持ちのMacintoshや実習室のディスプレイが何cmなのか調べてみて下さい。
set theCounter to 1 repeat while theCounter < 22 if theCounter is equal to 13 then set theMac to "MacBook " else if theCounter is equal to 15 then set theMac to "MacBook Pro " else if theCounter is equal to 17 then set theMac to "MacBook Pro " else if theCounter is equal to 21 then set theMac to "Mac Cinema Display " else set theMac to "Convert: " end display dialog theMac & theCounter & " inch is " & theCounter * 2.54 & " cm" set theCounter to theCounter + 1 end repeat
AppleScriptでは、言霊やJavaでいうところの%(整数剰余)は、「mod」で記述します。 次のプログラムは、カウンタの値を1つずつ大きくしていますが、整数剰余を使っていますので、 theCounterの値がthePeriodの値より大きくなることは絶対にありません。 結局、theCounterがループ変数になっており、thePeriodが周期になっています。
set theCounter to 0 set thePeriod to 8 -- 周期を仮に8としています。 repeat display dialog theCounter set theCounter to (theCounter + 1) mod thePeriod end
ループ変数と整数剰余を用いると、ある値nを、最小値minから最大値max未満(←未満であることに注意)まで の間で、m間隔で周期的に値を変化させることができます。 minやmaxおよび、mにset文で、適当な整数値を代入していますが、 (max - min)がmで割り切れる場合には、どのような場合でも動きますので、値を変えて確かめて下さい。 なお、マイナス2つの「--」は、AppleScriptではコメントとして認識されます。
set min to 10 -- 最小値を仮に10とします set max to 100 -- 最大値を仮に100とします set m to 5 -- 間隔を5と仮にします set theCounter to 0 -- 剰余は0〜割数-1の周期で動くので最初は0にしておきます set thePeriod to (max - min) div m -- 差分を間隔のmで割って周期を求めます repeat set n to (theCounter mod thePeriod) * m + min -- カウンタの値を周期で割った剰余に、間隔のmを掛けています。 -- それに、最小値を足してあげます。 display dialog n set theCounter to theCounter + 1 -- カウンタの値は1つずつ大きくしていきます。 end
同じプログラムをループ変数に間隔を掛けるような式を使わない形で、書き直してみます。 最初のminやmax、およびmに代入する部分の3行は省いています。 変数nに間隔mを足し込んでいますが、最小値minを引いて上げます。この括弧で囲まれた部分式は、 繰り返されるたびに0〜theDifferenceの間で、m間隔で大きくなっていきます。 しかし、theDifferenceで整数剰余を取っていますので、それより多くなることはありません。 それの結果に最小値のminを足しこんでやります。 これでこのプログラムでnの値が必ずmin以上max未満になることがわかると思います。
set n to min -- nを最小値に設定しておきます set theDifference to max - min -- 差分を求めています repeat set n to ( n + m - min ) mod theDifference + min -- n に mを足していきながらも、最小値を引きます。それを整数除算を使って差分よりは大きくならないようにします。 -- そして、最小値を足してあげます display dialog n end
次のプログラムは課題4-9をAppleScriptで記述したものです。 大の月か小の月かを求めるところで、andやorが用いられているのがわかります。
display dialog "Please Input MonthDay(mmdd)" default answer "0131" set monthDay to (text returned of result) as integer set theMonth to monthDay div 100 set theDay to monthDay mod 100 set countMonth to 1 set countDay to 0 repeat while countMonth < theMonth if countMonth = 2 then set countDay to countDay + 28 else if countMonth mod 2 = 0 and countMonth < 8 or countMonth mod 2 ≠ 0 and countMonth > 8 then set countDay to countDay + 30 else set countDay to countDay + 31 end set countMonth to countMonth + 1 end set countDay to countDay + theDay
言霊で紹介した脱出文は、AppleScriptにも存在します。 exit文は、repeat文中で使われると、その繰返しを終了させます。
if <終了条件> then exit
次のプログラムは、1から10までの数を表示するものですが、「, 」(カンマ)で区切って表示させて います。
set theValue to 1 set theMessage to "" repeat set theMessage to theMessage & theValue if theValue > 9 then exit repeat set theMessage to theMessage & ", " set theValue to theValue + 1 end display dialog "Sequence: " & theMessage
更に脱出条件で繰返しを終了させる繰返し文も存在します。repeat until文は終了条件が満足されたら、繰返しを 終了させます。終了条件が満足されないうちは何回も繰返しを行ないます。repeat while文の逆みたいな感じです。
repeat until <終了条件>
-- 繰返したいこと
end
次のプログラムは、1から12までの整数を受け取るものです。変数の初期値を0にしていますので、 繰返しに突入し、ユーザから1から12までの整数を受け取った場合だけ、繰返しを抜けます。
set theValue to 0 repeat until theValue > 0 and theValue < 13 display dialog "Input month (1~12) " default answer "1" set theValue to (text returned of result) as integer end display dialog "Your Month is " & theValue
言霊ではループ変数の変化を記述する専用の繰返し文はありませんでしたが、 多くのプログラミング言語では、ループ変数を使いながら繰返しを行なわせるための制御文が存在します。 C/C++/Java系のプログラミング言語では、for文と呼ばれています。 それは、Javaをやったときにでもご紹介することにして、AppleScriptでこのfor文に対応するrepeat文の 文法規則を以下に記します。[ ] は省略可能であることを意味しています。
repeat with <ループ変数名> from <初期値> to <最終値> [ by <間隔> ]
-- 繰返したいこと
end
初期値や、最終値、およびオプションで入れることができる間隔は、それぞれ整数の式になっていれば どのようなものでも記述して構いません。以下に簡単なサンプルを上げておきます。 100から0にむけて5ずつ減らしながら値を表示するものです。
repeat with i from 100 to 0 by -5 display dialog i end
次のプログラムはこのrepeat文を使って、言霊で記述したようなカレンダー表示をさせてみるものです。 同じように1桁の日が右に揃うように涙ぐましい努力(前に余計な空白をいれる)をしています。
set theCalendar to "" repeat with theDay from 1 to 31 if theDay div 10 < 1 then set theCalendar to theCalendar & " " -- 1桁の日のために空白を余分にいれる end set theCalendar to theCalendar & theDay & " " if theDay mod 7 = 0 then set theCalendar to theCalendar & return -- 7日ごとに改行を入れる end end display dialog theCalendar
AppleScriptでは、メソッドの定義は、以下のように記述します。
on <メソッド名> ( )
-- メソッドの中での処理
end
また、メソッドの呼出しは、以下のように記述します。[]で書かれているように、myは省略可能ですが、 アプリケーションを外部制御しているときなどには必要になってきますので、大抵つけるようにした方がよい でしょう。
[my] <メソッド名>( )
次のプログラムは、2回ダイアログを表示する twoTimesという名前のメソッドを定義して、プログラム本体の方から呼び出しています。 なお、AppleScriptのコメントは、--(マイナス2つ)で始まります。
my twoTimes() -- メソッドの呼出し on twoTimes() -- メソッドの定義 repeat 2 times display dialog "Hello Macintosh" end end
AppleScriptでも、メソッドの仮引数の定義の仕方は、3〜4種類あるのですが、 ここではJavaに似た形の一番簡単な定義の仕方を紹介します。 パラメータを持つメソッドの定義は、以下のように丸括弧の中に仮引数の名前を記述します。 仮引数の変数名は、例によって適当な名前をつけることができます。
on <メソッド名> ( <仮引数の変数名> )
-- メソッドの中での処理
end
たとえば、貰った値をインチにして表示するメソッドは次のように記述します。
on convertToInch( cm ) display dialog "Result: " & cm & " cm is " & cm / 2.54 & " inch." end
呼出し側は、メソッドを呼ぶ際に、丸括弧の中に実引数の式を記述します。 この式が評価されてから、メソッドの仮引数の変数に代入されます。
[my] <メソッド名> メソッド名( <実引数の式>)
先ほどのを、convertToInch呼び出して使ってみます。
my convertToInch( 23.2 )
仮引数が複数ある場合は、次の例のように「,」で区切って仮引数を並べます。 呼出し側もその順番で実引数を式で記述していきます。次の例は、xのn乗を表示するメソッドです。 3の6乗を表示させています。
on exponential(x, n) -- 2つの引数を貰っている set theAnswer to 1 repeat n times set theAnswer to theAnswer * x end repeat if n = 0 then display dialog "結果: " & x & " の 0 乗は、1" else display dialog "結果: " & x & " の " & n & " 乗は、" & theAnswer end end my exponential(3, 6) -- 呼び出すときは、評価された実引数が順番に仮引数に代入される。3→x、6→n
なお、AppleScriptでは、コンソールに出力するというようなコマンドはありません。 display dialogは、割と大きく表示できて、日本語なら横24文字ぐらい、縦50行ぐらい表示できますので、 文字列の変数に&演算子を使って表示するための変数に追加しておいて、最後に一気に表示させます。 下のプログラムで&演算子で繋がれた文字列の最後のreturnは、改行コードを示しています。
set theMessage to "" -- 空の文字列を最初に作ります set theCount to 1 repeat 40 times set theMessage to theMessage & theCount & " inch is " & (theCount*2.54) & " cm " & return set theCount to theCount + 1 end display dialog theMessage
AppleScriptの最大の長所はExcelなどのアプリケーションを直接外部から制御できることにあります。 たとえば40人分のデータについて、ExcelのRANDBETWEENやIF関数を使ってやったようなことを AppleScriptで記述するには、次のように記述します。 乱数を発生させるために標準装備のrandom numberというコマンドを使っています。 また、Excelではrowが行、行の中ではcellが1つのセルを表します。繰返しの中で、 そのセルの値を乱数の値で設定し、グレードに応じて、1つ右のセルに文字列を設定しています。
tell application "Microsoft Excel" -- Excelに制御を行なわせます make new document -- 新しく文書を作ります activate -- Excelを前面に持ってきます set rowNumber to 2 -- 2行目から始めます repeat 40 times set thePoint to random number from 0 to 100 -- 乱数を発生させます set value of cell 1 of row rowNumber of sheet 1 of document 1 to thePoint if thePoint ≥ 80 then set theGrade to "A" else if thePoint ≥ 60 then set theGrade to "B" else if thePoint ≥ 40 then set theGrade to "C" else set theGrade to "D" end set value of cell 2 of row rowNumber of sheet 1 of document 1 to theGrade set rowNumber to rowNumber + 1 end end
何行も実行結果を表示する方法としては、 AppleScriptにきちんと対応しているmiと呼ばれるテキストエディタを駆動させます。 1行はparagraphというクラスになっていますので、1行はparagraphを作って(make new)していきます。 このときにwith dataで文字列を指定すると1行表示される文字列として扱われます。 また、at after last paragraph of document 1は、最初に作った新しい文書の「最後の行の後」という位置を示しています。 この方法を使えば、実行結果をmi上でファイルとして保存することができます。
tell application "mi" make new document -- 新らしい文書を作ります activate -- 前面にmiを表示します。 set theYear to 1926 repeat 64 times make new paragraph at after last pargraph of document 1 with data "西暦" & theYear & "年は昭和" & (theYear-1925) & "年です。" set theYear to theYear + 1 end end