| ▲ | プログラムがただ動くだけでは満足しない。数十手ぐらい先を読む棋士のごとく、何通りものプログラミング方法を考えてベストの手段を選択するのがプロ。 |
|
|
| ▲ | エラーの回避手段をあらかじめ用意したり、サブルーチンを使ってプログラムを分かりやすく、効率的に、再利用可能な形にまとめあげることが肝心。プログラミングより先に、全体の解決手段(ソリューション)の青写真を描くことも重要だ。 |
連載[5-1] プロと素人のスクリプトはどこが違うか
| ただ「動けばいい」では永遠に素人 |
| 打つ手が3つ4つ思い浮かべば一人前 |
| サブルーチン化で使い回しが利くスクリプトを |
| プログラミングのアイデアは無尽蔵? |
| 行き詰まったら自発的にエラーを発生して終了 |
| 誠に重宝「tryしてダメならon error」構文 |
| コピー先に同名ファイルがあってもノーエラー |
| AppleScriptでホストを操作しちゃう |
| プログラム手段より先にソリューションを考えよう |
|
《 ただ「動けばいい」では永遠に素人
》
|
|
|
」
|
先生っ、またお邪魔しますよっ! |
|
先生
|
おやおや、二人とも真っ黒な顔をして。 |
|
」
|
先生のおかげでゴールデンウィークもゆっくり休めました。 今月は「プロの技」を見せていただけるっていうんで、もすごく興味を持っちゃって、またまた二人一緒にやって来たってわけです。先生、プロのスクリプトってどこがどう違うんでしょう。 |
|
先生
|
まず、構造化プログラムとスパゲッティ・プログラムの違いがあるね。 色・艶・形・味・香り、そのうえ速くて旨いってところかな。 |
|
」
|
えぇっ、それじゃまるで、山形屋の海苔じゃないですか。 |
|
先生
|
そう、あらゆる物質の形状はすべて山形屋の「Nori-Format」に凝縮されているんだ。 |
|
」
|
?? |
|
先生
|
具体的に言えば、スクリプトが分かりやすくて、より短く,処理速度が速くて、そして一度作ったスクリプトが将来再利用可能で、しかもエラー処理へも綿密に対応している、といったところだろうかね。逆に素人が作ったプログラムは、グシャグシャでこんがらかったスパゲッティになりやすい。要するに動けばいいってレベルだね。そこから脱却するのが今月の目標だ。 |
|
《 打つ手が3つ4つ思い浮かべば一人前
》
|
|
|
」
|
う〜ん、つまり今日は「プログラミング論」ですか。 |
|
先生
|
そこまでかしこまらないが、同じことをするにしても、いろいろなプログラム方法がある。どれでもいいってものじゃなくて、最適な方法を考えようってことさ。 |
|
・
|
私達ですと、1つの方法を見つけられただけで満足してしまいますものね。将棋の名人は何百という手を読むといいますが、プロのプログラマーの方も何通りものプログラミング方法を思いつくのかしら? |
|
先生
|
1通りしか思いつかないようじゃプロとは言えないね。例えば前回のファイルメーカーProの例だけど、英語の月名を数字に変換するために前回はif文を使ったが、ほかに図1のような書き方もある。 |
|
」
|
前回と全く違うじゃないですか。 |
|
先生
|
前回のif文の連続は、ある意味では分かりやすいとも言えるんだが、その分だけどうしても冗長になってしまった。 もうちょっと詰めてみると、図1のような書き方もできるってことさ。 |
|
・
|
前回は「January」「February」っていう月の英語名を、「01」「02」って数字にするのでしたね。 確か、 if word 2 of myDate = "January" then set myMonth to "01" else if word 2 of myDate = "February" then set myMonth to "02" else : といったように、if文をたくさん並べたものでしたわ。 |
|
図1 今日の日付文字列(Monday, April,17,1994など)から月の数字("04"など)を得るスクリプト
![]() |
|
|
先生
|
図1は全然違うよね。まず月の名前をリストにしてmonthListという変数に入れておく。 myDateは、 "Monday, April, 17, 1995" といった日付を表す文字列だった。この月名「word 2 of myDate」と、リスト内の月名を1つひとつ比較していくんだ。 repeat while 条件 は、条件が成立している間ずっと処理を繰り返す。繰り返す内容は、tmpNumに1を足すだけだ。 |
|
・
|
条件が結構複雑ですね。 |
|
先生
|
具体的に説明しよう。 例えばmyDateが"Monday, April, 17, 1995"だとすると、word 2 of myDateは"April"。1回目の繰り返しではtmpNumは1だから、item tmpNum of monthList(monthListのtmpNum番目の項目)は"January"だね 。 両者は一致しないし(not equal)、tmpNumは13より小さいから(tmpNum<13)、repeat whileの条件が成立する。 するとtmpNumの値に1が足されて、次の繰り返しに入る。条件が不成立になるのは、tmpNumが4になった時だ。 この時はitem tmpNum of monthListが"April"になるからね。条件が成立しないと、繰り返しを抜けて次の set myMonth to tmpNum as string |
|
・
|
分かったわ。繰り返しを抜けた時のtmpNumの値が4だから、myMonthは"4"になります。 "April"を元に"4"が得られますわ、先生。 |
|
先生
|
そう。後は簡単だ。もし1桁だったら頭に"0"を付けてやるだけだ。 |
|
・
|
ポイントは、比較すべき対象をあらかじめリストにしておいて、repeat文で1つひとつ比較するところですか。 |
|
先生
|
まぁ、処理速度の問題とかもあるから、どんな時にもこのやり方がベストとは言えないがね。私が言いたいのは、こうしたやり方を何通りも考えて,状況によって使い分けられるくらいの余裕があれば一人前ってことだ。 |
|
《 サブルーチン化で使い回しが利くスクリプトを
》
|
|
|
」
|
先生、これ以外のワザっていうと、どんなものがあるんですか。 |
|
先生
|
よく使われるのが、変数の利用と、サブルーチン化だろうね。 |
|
」
|
変数はこれまでにも習いましたが、サブルーチンと言うのは? |
|
先生
|
サブルーチンはだね、簡単に言えば、一般的でほかでも使い回しができそうなロジックを独立して作っておくことなんだ。 そして必要な時にそれを呼び出して使えばいい。 |
|
」
|
へーぇ、アラジンの魔法のランプみたいなものですかねぇ。 |
|
・
|
この月名を数字に変換するスクリプトなどは、使い回しが利きそうですわね。 これをサブルーチンにするにはどうするのでしょうか。 |
|
先生
|
サブルーチンを作るには、onで始めてその後にサブルーチン名を付けて、続いて()内にパラメーターを指定する。 on サブルーチン名(パラメーター1,パラメーター2,…) (サブルーチンの内容) return 返すデータ end サブルーチン名 onとendで囲まれた一連の命令が一つのサブルーチンになるわけだ。 図1のスクリプトをサブルーチン化すると、図2のようになる。 |
|
図2 日付文字列を渡して月の数字を返すサブルーチン
![]() |
|
|
」
|
パラメーターというのは何ですか。 |
|
先生
|
サブルーチンに処理させたいデータだ。図2のサブルーチンは、日付文字列を処理して数字を返させるわけだから、パラメーターgivenDateとして日付文字列を与え、それを処理して月の数字をreturnさせる。 図1でmyDateだった部分が、サブルーチン内ではgivenDateになっている点がポイントだね。 |
|
」
|
サブルーチンを使う時はどうするんですか。 |
|
先生
|
単純にサブルーチン名を書けば、それが呼び出される。
my サブルーチン名(パラメーター1,パラメーター2,…) |
|
」
|
へぇー、サブルーチンって結構面倒くさいんですね。 |
|
先生
|
だが十分なメリットがある。呼び出す時に与えるパラメーターを変えるだけで、いろいろなデータを処理できるでしょ。 |
|
・
|
(current date as string)以外の日付文字列を与えてもきちんと数字を返してくるわけですね。 |
|
先生
|
そう、使い回しが利くってのはそのことなのさっ。 |
AppleScript救急隊事務局(ASQs) info-asqs@fsight.co.jp