« 今日の多治見は36度…… | トップページ | R・ナダルの優勝 »

2008年7月 7日 (月曜日)

問2:第5回

きょうは七夕……RunRevとは関係ないけど;短冊にスクリプトが上達しますようにと書いてみるのもいいかも知れない。

ということで、今回はいよいよ手順5です。

手順4で書いたスクリプトをテストしてみましたか? キチンとテストすると判るのですが、実は手順4のスクリプトはスクリプトとしては全く問題なく動くのですが、入力フィールドの質問を繰り返す無限循環に陥ってしまうのです。これは、スクリプトの問題ではなく、スクリプトによって表現したかったアプリケーションの流れ・構成が誤っていたということです。スクリプトが間違っていなくても誤りは起きる……そういうこともあるのです。

ではどこに「発想・考え方」の誤りがあったのか、それを洗い出してみることにします。結論を先に言ってしまうと、【スクリプト2の8】では、answerコマンドで尋ねているのは「次の入力フィールド」なのですが、するとその指定された「次の入力フィールドでも」エンターを押すことで同じ質問が出てしまいます。これが無限循環につながるわけです。ではこれを避けるにはどうしたら良いのか……。質問の仕方を変える;つまり仮説の正当性が立証されなかったら、仮説を変えるしかない;これが論理的思考の基本である。今読んでいる畑村洋太郎さんの『続 直観でわかる数学』(岩波書店 ISBN 4 - 00 - 006243 - 3 ¥1500-)にも次の様な一文があります。曰く『論理でできることが何か仮にあるとしたら、それは正しいかどうかを確かめる検証だけである。論理を武器にして答えを見つけたり、何かを作り出すことはできないのである』

answerコマンドで尋ねる「入力フィールド」の次にそのフィールドに入力したい値を訪ねるようにしたらどうでしょうか? つまり、次の様な流れを考えてみるということです。

【表2の3】


Itoh032

<上の表を流れにすると>
入力のあったフィールドが『BaiKa』ならば、answerコマンドで『次の入力フィールド』を尋ねる;次の入力フィールドが『GenKa』ならば、askコマンドで『GenKaフィールドに入力する値』を答えさせる;『GenKaフィールドに入力する値』が正しい値ならばNeIreハンドラを実行する;正しくなければ、最初に戻る

大雑把に言うとこんな感じになります。
ここでまた新しいコマンド「ask」の出現です。answerコマンド同様askコマンドも使用者側に答えを求める為のコマンドですが、answerコマンドではボタンを表示しそのボタンのどれかから答えを選択するのに対し、askコマンドでは文字入力用のテキスト・ボックスが表示され、そこに自由に答えを入力することになります。

以下に「askコマンド」を詳しく説明してみます;“Displays a dialog box with a question, a text box for the user to enter a response, and OK and Cancel buttons.”「質問の書かれたダイアログ・ボックスと使用者が答えを入力するためのテキスト・ボックス、さらにOKとキャンセルのボタンを表示します」。“Use the ask command when a handler needs to get information from the user before continuing.”「ハンドラが次の処理に移る際に使用者からの情報を必要とする場合にaskコマンドを使います」。

askコマンドは次の様な形で使われます。
ask question with defaultResponse
ask 質問 with 初期設定の答え

具体例で言うと;ask “put NeIreritu into me” with “99.99”という形です。answerコマンドのメッセージ同様、question(質問)は引用符“”で囲います。defaultResponse (初期設定の答え)は無くてもかまいません。その場合、withも省略します。
答えの入力されたテキスト・ボックスの内容、OKボタンとキャンセル・ボタンの押された時の内容は、answerの時と同じせ変数「it」に入れられます。従って、後の処理ではこの変数「it」の内容を参照していきます。


今までに書いた【スクリプト2の8】までを参考にして書き上げたのが次の【スクリプト2の9】です。

【スクリプト2の9】
on enterInField
if isNumber(fld the target) then
if the target contains “BaiKa” then
put empty into fld “GenKa”
put empty into fld “NeIre”
answer “what do you enter next ?” with “GenKa” or “NeIre” or “Cancel” as sheet
if it is “Cancel” then exit to top
if it is “GenKa” then
ask “put GenKa into me” with “123”
if isNumber(it) then
put it into fld “GenKa”
NeIre
else
select text of fld “BaiKa”
end if
end if
if it is “NeIre” then
ask “put NeIreritu into me” with “99.99”
if isNumber(it) then
put it into fld “NeIre”
GenKa
else
select text of fld “BaiKa”
end if
end if
end if
if the target contains “GenKa” then
put empty into fld “BaiKa”
put empty into fld “NeIre”
answer “what do you enter next ?” with “BaiKa” or “NeIre” or “Cancel” as sheet
if it is “Cancel” then exit to top
if it is “BaiKa” then
ask “put BaiKa into me” with “246”
if isNumber(it) then
put it into fld “BaiKa”
NeIre
else
select text of fld “GenKa”
end if
end if
if it is “NeIre” then
ask “put NeIreritu into me” with “99.99”
if isNumber(it) then
put it into fld “NeIre”
BaiKa
else
select text of fld “GenKa”
end if
end if
end if
if the target contains “NeIre” then
put empty into fld “GenKa”
put empty into fld “BaiKa”
answer “what do you enter next ?” with “BaiKa” or “GenKa” or “Cancel” as sheet
if it is “Cancel” then exit to top
if it is “BaiKa” then
ask “put BaiKa into me” with “246”
if isNumber(it) then
put it into fld “BaiKa”
GenKa
else
select text of fld “NeIre”
end if
end if
if it is “GenKa” then
ask “put GenKa into me” with “123”
if isNumber(it) then
put it into fld “GenKa”
BaiKa
else
select text of fld “NeIre”
end if
end if
end if
else
answer “put the number first, shall you ?”
select text of fld the target
end if
end enterInField

on returnInField
enterInField
end returnInField

on GenKa
put round((1-fld “NeIre”/100)*fld “BaiKa”) into fld “GenKa”
end GenKa

on BaiKa
put round((fld “GenKa”/(1-fld “NeIre”/100))) into fld “BaiKa”
end BaiKa

on NeIre
put round((1-fld “GenKa”/fld “BaiKa”)*100,2) into fld “NeIre”
end NeIre


この【スクリプト2の9】で注意すべき表現は次の二点です。
isNumber(fld the target) ・ isNumber(it);このようにisNumber()の()内にはコンテナを使用できるので、このような表現が可能になります。fld the targetは、例えば売価フィールドでリターンが発生した場合、isNumber(fld “BaiKa”)と書くのと同じことになります。同様に、answerでボタン“NeIre”が押された場合には、isNumber(it)の「it」の内容は「fld “NeIre”」になり、isNumber(fld “NeIre”)と書くのと同じことになります。

exit to top;これはRunRevでは珍しく成句としての制御構造で、必ず「exit to top」の形で使用します。“Use the exit to top control structure to stop executing the current handler and suppress pending messages.”「exit to top制御構造は、現在実行中のハンドラの停止し、保留中のメッセージを消去します」。このexit to top制御構造は、pass制御構造と役割が良くにていますが、最も違う点は『保留中のメッセージ』を次へ引き継ぐ(pass)か終わらせてしまう(exit to top)かです。つまりpass制御構造ではメッセージを別の場所で捉えて使うことができるのに対し、exit to top制御構造ではメッセージをそこで終わらせてしまいそのメッセージを開始した直前の状態に戻すことになります。

|

« 今日の多治見は36度…… | トップページ | R・ナダルの優勝 »