« 問1用ダウンロード | トップページ | おばけつぶやき帳 »

2008年6月16日 (月曜日)

問2:第2回

手順2

さて手順2では、RunRev以外のソフトで作成した画像をRunRevに取り込んでカードのオブジェクトとして使用する方法から説明していきます。

ここで作成する画像は、【図2の2】のようなものです。【図2の2】の元となる文字列は、マック上のPagesというソフトのワープロ機能を使って作成しています。使用しているフォント(書体)は「ヒラギノ角ゴProN」でタイプフェイス「W6」、サイズは「20」を使用しています。これはマックの場合の設定です。Windowsでは同じフォントは無いかも知れませんので、自身で自由に選択して下さい。

【図2の2】


Itoh022

この設定で書いた文字を画面キャプチャ用のソフト(Snapz Pro X)を使って画像に変換し、画像処理用ソフトでトリミングを行った後、コピー&ペーストでRunRevに取り込んでいます。

画像取り込みの際は、まず画像処理用ソフト側で必要な範囲を選択してコピーを行い、RunRev側のメニューから「Edit」→「Paste Image」を選択することで【図2の3】、RunRevのカード上の新しいオブジェクトとして表示されます。

【図2の3】


Itoh023

その後、フィールドを三つ作り【図2の2】で空白になった部分に重ねて、【図2の4】の状態にします。【図2の4】で点線上に1、2、3となっているのがフィールドです。それぞれのフィールド名は「BaiKa」、「GenKa」、「NeIre」とします。

【図2の4】


Itoh025_2

カードが上図のようになったところで一度テストをしてみます。
今回はスクリプトを書く場所をカードにするので、RunRevのApplication Browserを使ってカードを選択することにします【図2の5】。Application Browserカードを選択した状態で【図2の6】マウスの右ボタンをクリックするとメニューが表示されます。そのメニューから「Edit Script」を選択すると【図2の7】、スクリプト・エディター(スクリプト編集用ウィンドウ)が現れます【図2の8】。


【図2の5】


Itoh026

【図2の6】


Itoh027

【図2の7】


Itoh028

【図2の8】 このスクリプト・エディタはRunRevのデフォルトのものとは異なりますが、基本機能は同じです。


Itoh029

上の操作でスクリプト・エディタが現れたら、次のハンドラをタイプしていきます。

【スクリプト2の1】

on enterInField
put the target
end enterInField

on returnInField
enterInField
end returnInField

on tabKey
enterInField
pass tabKey
end tabkey


ここで新たに登場したのが「target(ターゲット)」という関数と「pass(パス)」という制御構造です。

target関数は通常「the target」という形で使われますが、次の様な意味を持っています。“Returns the object which received the message that started execution.” 「メッセージ・ハンドラの実行を開始したメッセージを受けとったオブジェクトを返します」。“Use the target function within a message handler to determine which object originally received the message.”「メッセージ・ハンドラ内で、最初にそのメッセージを受けとるオブジェクトを知りたい時に、target関数を使い」ます。
モノは試しということで……上のスクリプトを実行するためにフィールド内でエンター或いはリターン、タブを押してみると、それぞれどのフィールドでエンター或いはリターン、タブが押されたのかをメッセージボックスに表示します。今回は、この関数を使うことでどのフィールドで数値入力があったかを判断し、次に数値入力をするフィールドが何かを尋ねることで「算出すべき値」、つまりどの算式を使えば良いのかを判断できるはずです……ネ

次にもう一つの新顔pass制御構造ですが;“Stops the current handler and passes the message to the next object in the message path.”「現在のハンドラを停止しメッセージ・パス内の次のオブジェクトにそのメッセージを渡します」。“When the pass control structure is executed, any remaining statements in the handler are skipped. Hence, the pass control structure is usually used either at the end of a handler or within an if control structure.”「pass制御構造が実行されると、ハンドラ内の残りのステイトメントは全て実行されずに飛び越されてしまいます。それ故、pass制御構造は通常ハンドラの最後かif制御構造の中で使われることになります」。
何の意味だかよく判らないと思いますが、ここではその辺りは詳しく詮索しないことにして、tabKeyハンドラを実行することで何がどうなるのかを実際に試してみることにします。先程書いた【スクリプト2の1】(カード・スクリプト)のtabKeyハンドラに次の一行「put “This is tabKey !!”」を追加してみます。

【スクリプト2の2】

on enterInField
put the target
end enterInField

on returnInField
enterInField
end returnInField

on tabKey
enterInField
pass tabKey
put “This is tabKey !!”
end tabkey


ブラウザ・モードに戻り、このスクリプトを実行してみます。タブでフィールドを移動しながらメッセージ・ボックスにどんな表示がでるのかを確認して下さい。
 次にまたカード・スクリプトの編集に戻り、tabKeyハンドラの「pass tabKey」を一行をコメント化して実行を止めてみます。

【スクリプト2の3】

on enterInField
put the target
end enterInField

on returnInField
enterInField
end returnInField

on tabKey
enterInField
-- pass tabKey
put “This is tabKey !!”
end tabkey

このスクリプトの動きを確認するため、今一度ブラウザ・モードに戻り、タブでフィールドを移動しながらメッセージ・ボックスにどんな表示がでるのかを確認して下さい。何がどう違うのか判りましたか?

実は「pass tabKey」をコメント化する前には、タブによるフィールド移動ができたはずですが、コメント化することにより通常のタブ機能が働くなりフィールドの移動ができなくなります。これは通常のタブ機能に使われる「tabKey」メッセージがtabKeyハンドラにより受けとられ、それ以上伝わらなくなるからです。逆にコメント化することによって、それまで表示されなかった“This is tabKey !!”という一行がメッセージ・ボックスに表示されるようになります。これは、「tabKey」メッセージを他のオブジェクトに引き渡す(pass)ことがないためtabKeyハンドラ内の全てのステイトメントが実行されるからです。
これがpass制御構造の役割です。
つまりpass制御構造があると、それ移項のステイトメントの実行は飛び越されます。なので“This is tabKey !!”という一行はメッセージ・ボックスに表示されません。その代わりに「tabKey」メッセージはtabKeyハンドラで停止することなく生き続け、tabKeyハンドラの外に抜け出してシステム・レベルまでメッセージとして伝わっていき、タブによるフィールド移動が可能になるわけです。
これとは逆に、pass制御構造がコメント化された場合(元々ない場合も)「tabKey」メッセージはtabKeyハンドラ内で完結してしまうため、それ以上どこにもメッセージは伝わることなく、通常のタブ機能が効かなくなってしまうわけです。
このようにpass制御構造には幾分慣れを必要とする癖がありますので、色々自身で試してみて使い方を習得するしかありません。


さてここで思い出して欲しいのが、今回は「スクリプトをカードに書いている」ということです。問1でフィールドに書いていた「enteInField」「returnInField」のハンドラを今回はカードに書いている(カード・スクリプト)ということですが、これがメッセージを発するオブジェジェクとそのメッセージを受けとるオブジェクトとが異なっても良い、ということを示してます。つまり、メッセージは伝わるということで、その伝わり方の法則と優先順位のことをメッセージ・パス(単に「パス」とも;message path)(この場合のパスは、passではなく道筋・経路を表すpathです)と呼びます。
メッセージが発生した時に、メッセージ・パス内のどこでそのメッセージが発せられたかを知るための関数がtarget関数なのです。

では今回は何故フィールドではなくカードにスクリプトを書いたのか、ということですが……;
理由は単純で、三つあるフィールドの各々に似た様なスクリプトを書かなければならないのを避けたい……つまり、間違いが発生しやすい方法を回避する、ということがあります。それに面倒くさい!!何かの理由でスクリプトを書き直したり、追加したりする時に、そのチェックが大変であるということです。スクリプトを書く際に自身が「面倒くさいナ」「うっ陶しいな」と感じることは、結局スクリプトの誤記や記入漏れなどの原因となり、スクリプトの実行エラーを引き起こすからです。それ故、こうした煩雑さを避けるために今回はカードにスクリプトを書いたわけです。ここでは詳しくは扱いませんが、実は今回書いたカード・スクリプトはそのままスタック・スクリプトとしても問題なく動くはずです。

スクリプトをどこに書くかは、個人の癖、好み・スタイルもありますし、作成するアプリケーションの大きさや複雑さにも左右されるでしょうし……沢山スクリプトを書いていくうちに自ずと自分のスタイルができあがるだろうと思います。

|

« 問1用ダウンロード | トップページ | おばけつぶやき帳 »