RealBasic University

このコラムはStone Table Softwareのオーナーであり、またREALbasic Developerの編集者でもあるMarc Zeedar氏により書かれたものを、著者の許可を得て翻訳したものです。この翻訳はHREM Researchにより提供されています。この日本語版へのご意見はRBU-Jまでご連絡下さい。

URL: http://www.applelinks.com/rbu/073/
INDEXに戻る

DoRbScript:パート III

前回、私はRbScriptをリモート操作するAppleScript対応のプログラムであるDoRbScriptを制作するためのステップの概要をまとめました。そのステップとは次のようになります。

  1. 我々のアプリ用にAppleScriptの"dictionary"を作成する
  2. アプリを作成し、渡されたAppleイベントを処理する
  3. プログラムをテストするためにAppleScriptを作成する

1番目は前回行ったので、今回は2番目を行うことにしましょう。

DoRbScriptのアプリケーションを作成する

まず始めに、新しいREALbasicプロジェクトを開始してください。ツールパレットからRBScriptアイコンをWindow1にドラッグしてください。

次に、新しいクラスを追加(Fileメニューの"New Class")して、それをappとします。それに"アプリケーション"のsuperを与えます。アプリケーションクラスだけがAppleイベントを受信するので、こうしなければなりません。つまり、アプリケーションクラスでないと、プログラムはそこに送信されたAppleイベントのメッセージを認識しません。

さて、appオブジェクトにいくつかの属性を追加していきましょう(appを開いて、Editメニューから"New Property"を選択)。まず次を追加してください。

 error as integer 
theResult as string

これは、実行中のスクリプトについての情報(すなわち、エラーメッセージあるいはどんな結果でも)を保存するために用います。

ここでRBScript1を開きましょう。そこにいくつかのイベントが入っているのが分かるでしょう。それらはスクリプトが実行中の間に発生するものです。まず始めはCompilerErrorです。渡されたスクリプトにはエラーの含まれる可能性があるので、そのエラーをリポートしたいですね。だから次のようにして、そのエラー情報を保存しましょう。

   app.theResult = errorMsg 
app.error = errorNumber

appオブジェクトに追加した属性の内部に、これらを保存していることに気がつくでしょう(それが名前の前に"app."がつく理由です。そうしてRBはどこに属性があるか知ることができます)。

次は、printイベントです。そのコードは次のようになります。

 app.theResult = msg 

RBScriptからデータを取り出すためには、"print"コマンドを使います。"print"されるすべてのものは、このイベントへ送信されたmsg属性に現れます。ここでしていることは、結果を文字列属性に保存することです。

最後に、RuntimeErrorイベントに行き、次を入力してください。

 app.error = 0 

これは私が作った任意のエラー番号です。我々のプログラムでは、-1はエラーなしを、0はランタイム・エラーを意味し、そしてすべての正数はRBのオンライン・ヘルプで示されているエラーコードに対応します(RBScriptの下で)。

それが済めば、あともう少しです。次に、送信されたAppleイベントを取り扱うためのコードを追加しなければなりません。これはappオブジェクトのHandleAppleEventイベントの内部で行います:

   if not (eventClass = "misc" and eventID = "dorb") then 
error = -1
window1.rbScript1.source = event.StringParam("----")
window1.rbScript1.run

while window1.rbScript1.state = 1
wend

event.replyInteger = error
event.replyString = theResult
return true // handled
end if

return false // not handled

この訳の分からないものはなんでしょう!?心配はありません。それほど難しいことではありませんよ。

まずここで行うことは、どんなAppleイベントが送信されたかをチェックすることです。つまり我々はある1つの種類のイベントだけを処理したいわけです。すべてのAppleイベントは、クラスとIDの2つの4文字コードを渡します。数多くの標準イベントが存在しますが、我々のものはカスタマイズされたものです。それは"misc"(その他)のクラスで、IDは"dorb"("do RB Script"の意味)です(これは前回我々が作成したaeteリソースに使用したものと一致することに気づくでしょう)。よって1行目は、それは受信されたイベントであるかをチェックします。もしそうならば、それを処理しますが、それでなければ処理しません。

Appleイベントを扱うために、いくつかの簡単なことを行います。まず最初に、error属性を-1に初期化します(-1は"エラーなし"と定義したことを忘れないでください)。

次に、渡されたAppleイベントからスクリプトを取り出し、rbScript1source属性にそれを割り当てます。しかし実際はなかなか難しいようです。これは実際よりも難しく見えます。eventはAppleイベントのオブジェクトで、そのstringParam属性はRBスクリプトのコードを含んでいます。今のところ、"----"パラメータを無視してください――それは、特別な種類の文字列を要求しないことを意味します。それを取り決められた応答と思うことにしましょう。

RBスクリプトのソースコードがsource属性に保存されたあとで、rbScript1runするよう伝えます。

スクリプトが実行中の間、それが終了するのを待つためにループの中に入ります。.state = 1の行は、スクリプトが実行中であることを意味します。スクリプトが終了した時、あるいはエラーのある場合にはstateは異なる値を返し、ループは終了します。

スクリプトが終了すれば、結果をeventオブジェクトに保存します。eventオブジェクトは結果を返すために特別な属性を持ちます。我々はエラーコードと結果のテキストをそれぞれ保存するために、replyIntegerreplyStringを使用します。

最後は、Appleイベントを処理したことを意味するtrueを返すことです。結果はAppleイベントを送信したプログラム(この場合は、AppleScript)に自動的に返されます。

今回はここまでです。今週のチュートリアルの完全なREALbasicプロジェクト(リソースを含む)を手に入れたい場合は、ここからダウンロードしてください。

次週

DoRbScriptをテストするため、AppleScriptを書きます。

Letters

今回のemailは、Steenさんからテキストの構文解析に関する質問です。

こんにちはMarcさん!

これは単純な質問だと思います。

私は簡単なapplescriptを作りました。そこではeditfield1に、テキストを書いたりペーストしたりします。それからregexを使って内部検索を行います。目的の単語が見つかれば、テキストの全行がeditfield2へ入力されます。そして見つかった単語はedifield3へ入力されます。

それで私の質問は次のようになります。Realbasicに1行づつ読み込ませて、'単語'が見つかった場合はその行を取り出してeditfieldに入力し、見つかった単語を別のeditfieldに入力するにはどのようにしたら良いでしょうか?

お返事待っています。もちろん、私のメールをウェブや雑誌に掲載しても構いません。これも他の人たちの役に立つと思います。

REALbasic Developer Magazineを楽しみにしています。

よろしくお願いします

Steen

こんにちは、Steenさん!

あなたの質問は2つの部分から成ります。始めに、あなたはテキストを1行ずつ分解しようとしています。それからテキストを単語単位で解析しようとしています。

このどちらの機能も、nthField関数を使えばREALbasicでは比較的簡単にできます。nthFieldは、解析しているどんなテキストでも、渡すものを区切り子として使用し、"n番目"のフィールドを返す優れた構文解析のコマンドです。

コマンドのパラメータは次になります。

nthField(sourcetext, delimiter, fieldnumber)

結果は文字列です。あなたの要求したフィールド番号が存在しないならば、空の文字列が返されます。

我々の場合では、行ごとにあるテキストを解析したいですね。行は改行で区切られているので、chr(13)を見つけ出します。コマンドは次になります。

 editField2.text = nthField(editField1.text, chr(13), 3) 

このコマンドはeditField1の3行目をeditField2に入力します。

それから、その行から個別の単語を抜き出したい場合は、次を使用します。

 editField3.text = nthField(editField2.text, " ", 3) 

これはeditField2の3番目の単語をeditField3へ入力します。この場合、我々はeditField2を検索しています(そこにはテキストが1行あります。全てのテキストがあるeditField1ではありません)。そしてスペース(空白)で区切られたフィールドを探しています。

ここでちょっとだけ複雑になってきます。一般的に、英語では単語間はスペースで区切られています。しかし時には例外もあります。例えば、ハイフンで結ばれた単語は分離した単語としてか、それとも1語として数えるべきでしょうか?ピリオド(スペースではなく)を含むURLは、1語として数えるべきでしょうか?つまり単語をどのように捕らえて数えるかはあなた次第です。あなたはREALbasicがサポートする上級者向けのテキストのパターンマッチ・プログラムであるRegEx(Reagular Expressionの省略形)について触れました。より正確な単語抽出をするためにそれを使用できるでしょうが、それは必要ないかもしれません。例えば、単語間の区切りとしてスペースを使うだけで99%うまく行きます。

ここに、私がいまちょうど説明したことを行う簡単なデモがあります。テキストは始めのフィールド(私はサンプルとして、このチュートリアルからテキストを使用しました)にあり、2番目には行、3番目には単語が抜き出されます。ポップアップ・メニューでは行を選択することができ、3番目のフィールドでは表示したかった単語が表示されます。次は実行中の画像です。

このプロジェクトを手に入れたい場合は、ここからダウンロードしてください。

これであなたの質問に答えられたと思います。


RBU-Jの通知サービス!コラムが発表されるたびに日本語版REALbasic Universityのお知らせの emailがあなたに届きます。登録・削除は ここ から。

INDEXに戻る