Foltia with AppleScript

Foltia animelockerのトラブルシューティング

コードは短ければ短いほどよい repeat編:アップルスクリプト

Repeat文はどんなプログラム言語でも見られますね。 AppleScriptでも、いろいろなRepeatの構文がありますが、そういう分類みたいな堅い話はいくらでもネット上に記載がありますのでここでは割愛です。

Repeat文は長大なプログラムを短縮させることができるキーワードですが、リピート文の中のバグが発生したときに、どの入力がどのような理由でエラーを起こしたのかを知るのはなかなか難しかったりします。 アップルスクリプトエディターでは各ステップでどのように計算がされたかを表示させてバグの原因を突き詰めることが出来ます。

例えば、下の様なコードを記載します

set ls to {"ミカン", "オレンジ", "ハッサク"}

repeat with a in ls

    if a is "ミカン" then exit repeat

    log a

end repeat

return a

lsに含まれるStringのリストの中を左端から変数aに入力して"ミカン"という変数がでたらrepeat loopから抜ける、というスクリプトです。 ウインドウ左下の赤矢印をクリックして見ましょう。

左した赤矢印をクリックすると

そうすると上にミッドバーに、結果・メッセージ・イベント・返された値というタブが出てきます。 この返された値をクリックしてみてから実行して見てください。

そうすると。

(*ミカン*)

(*オレンジ*)

(*ハッサク*)

結果:

item 3 of {"ミカン", "オレンジ", "ハッサク"}

こんな形で結果が表示されます。 logと書かれた変数の内容が下に(* *)で囲まれて記載されているのが解るでしょうか?  こうやってLoop内で変数がどうやって移行していったかが解るわけです。  ただこの方法はWeb pageなどを見渡すような凄い長いStringを扱ったりすると、長大なStringで埋め尽くされてわかりにくくなります。 その場合は、前回扱った、LogOnConsoleRといった外部ファイルへ書き出す方法の方が解りやすくて良いです。

コードは短ければ短いほどよい Try編:アップルスクリプト - Foltia with AppleScript

アップルスクリプトのRepeat with構文の特徴

ここからは他言語などではちょっと考えにくいアップルスクリプト独特のポイントを記載して見ます。 先ほどのコードの結果、何かおかしく無かったですか?

本来lsに含まれる"ミカン"は1番目のアイテムなので、logにオレンジやハッサクが出ることは無いはずです。 結果を見るとitem 3 of {"ミカン", "オレンジ", "ハッサク"}となってます。 つまり変数aに入っているのはリストの中の各項目のString値ではなくて、lsの中の何番目のアイテムかという情報=item 1 of  {"ミカン", "オレンジ", "ハッサク"} は "ミカン" と同じではないと真偽判定されているのです。 対策としてRepeat loopの中で set a to a as stringとstringに変換してあげてもよいですが、もう少し一般解的なやり方は以下の様になります。

set ls to {"ミカン", "オレンジ", "ハッサク"}

repeat with a in ls

    set a to a's contents (*あるいは contents of a と書いてもよいです*)

    if a is "ミカン" then exit repeat

end repeat

 

return a -->"ミカン"

こうやってset a to a's contents aの内容をaとするという記載の入力が必要となるわけです。 これを知らないと「なんで?」ってなってアップルスクリプトを嫌いになってしまう方多いと思います。 

アップルスクリプトにはポインタの概念がない

Cなどではポインタといって変数の名前をアレイから取り出してセットすることが出来ます。 それを使うと変数名を定義するのにrepeat loopを使えるのでコードが短くなって良いんですが、アップルスクリプトでは変数名やレコードの属性名を計算で定義することは出来なくなってます。 例えば str1 , str2 , str3, str4といった変数を定義するといった場合全部書き出さなくてはなりません。 

まあ本当はレコードなどは一部可能なのですが、スクリプトが解りにくくなるのと実行速度がかなり遅くなるために敬遠されるみたいです。 run scriptというコマンドを使うのですが、もう少しほかのやり方を考えた方がスマートだったりします。

set a to {SONG:"β", gen:"ソルト"}

set a to a & (run script "return {Patient_ID:\"テスト\", Ringo:\"赤い\"}")

return a --> {SONG:"β", gen:"ソルト", Patient_ID:"テスト", Ringo:"赤い"}

 

でも変数名をrun scriptで設定しようとすると。

set ls to {"イチゴ", "ミカン", "キュウリ", "ハッサク"}

repeat with i from 1 to 4

    set var to (("set str" & i as string) & " to \"" & (item i of ls) as string) & "\""

    run script var

    log var

end repeat

 

return str1

-->error "str1変数は定義されていません。" number -2753 from "str1"

 

logを見てみると一応、run script上では変数への入力は出来ているようなのですが(下の様に)、 run スクリプトの外での変数の定義がされていない状態になります。

run script "set str4 to \"ハッサク\""

--> "ハッサク"

(*set str4 to "ハッサク"*)

そうするとスクリプト全文をこのrun script上で作成すれば良いことになるんですが、現実的にはかなりの力業ですし、視認性が悪くバグ取りも難しく、何より拡張性が低すぎます。 まあ何かの時に使えるかもしれないなと思ってますが・・。 ちょっとした話のネタぐらいにしかならないかもですね。 

 

次は一旦またFoltia関連のお話に戻ります。