【しばらく編集不可モードで運営します】 編集(管理者用) | 差分 | 新規作成 | 一覧 | RSS | FrontPage | 検索 | 更新履歴

CURL実開発講座 - *このページ作成者のブログ

目次

このページ作成者のブログ

Curlとは?

http://d.hatena.ne.jp/curl/

リッチクライアントの実開発に必要な知識

ここでは、リッチクライアントビジネスアプリケーションを、Curlで実際に開発する際に、 つまづきやすい問題を取り上げています。

 

例外について

Q.実行中におきたどんなイベントも、一箇所で取得したいのですが?

[回答]

Version4からRegistrationException?という、アプレット例外を一箇所で取得できるようになります。

しかし、予想される例外(ファイルオープンなど)は各部に書くべきです。

また、キャッチするべき例外にも種類があり、一括で取得するべきかは設計によるとおもいますので、 そのあたりは一概にはいえません。

 取得するべき例外の種類  ランタイム例外(NullDerefferenceException?)  異常処理例外(ArrayBoundsException? )  アプリケーション例外(CustomException? for Application)

ファイルオープン時などはwith-open-stream などを利用すると楽になるかもしれません。

また、例外を実行時に起こさないようにポイントとして、 {compiler-directives safe? = true} 'if-non-null' and 'type-switch' を利用して、なるべくNullとは関係ないソースを書くことをお勧めします。

印刷について

Q.印刷時にオブジェクトが画面からリプレースされるのを防ぎたいのですが?

[回答]

確かに、Curlのオブジェクトを印刷フレームに渡すと、 画面上にあるものが、消えてしまいます。

これを回避する方法は3つほどありますが、一番簡単なのは、 印刷フレームに渡した後に、元のところに再度戻してやる、という方法です。 瞬間的に画面上のオブジェクトがフラッシュするかもしれません。

これがいやな場合は、データから生成される、ファクトリーパターンを用いる方法もあります。 つまり、印刷時に、表示されているオブジェクトではなく、 新しく作成したオブジェクトを印刷フレームに渡す、という方法です。

また、表示されているオブジェクトであれば、gifやjpegとして画像化することが可能です。 オブジェクトの量によっては時間がかかる場合がありますが、 画面をピクチャーするという要求がある場合にはこの方法がよいでしょう。

Q.印刷ダイアログを表示せずに印刷したいのですが?

[回答] Ver4.0から可能になります。

また、Ver4.0では、これまで不可能だった、印刷時の紙の方向も プログラムから指定できるようになります。

イベントついて

Q.HTTP通信などを発生させるボタンのダブルクリックを防止したいのですが?

[回答]

ボタンのダブルクリックを禁止するのではなく、どんな時にはクリックさせないのか、を明確にし、 その判断でイベントを行わないようにしましょう。

フラグをグローバル変数として作成し、プロシージャなどでそのフラグを見るのが簡単です。

Q.プロシージャのコールを取りやめたいのですが?

[回答]

コールするプロシージャとコールされるプロシージャがあり、 コールするプロシージャは、ロックするべきかどうかにかかわらずコールするが、 コールされる側のプロシージャでロックするべきかどうかによって、 そのプロシージャ内の実行を取りやめたいような場合、 プロシージャをコマンドでラップし、コマンドの中でロックをかけるのがよいでしょう。 例をいかに示しますので参考にしてください。

例:ファイル保存の場合

ファイル保存を行うプロシージャ パッケージアクセス プロシージャを呼び出すコマンド パブリックアクセス コマンドを呼び出すコントロール

コマンドボタンをEnableにするのではなく、 Command and CommandContext? を利用すること

CommandContext?はアプリケーションで命名されたセットのコマンドを利用可能に します。

RecordSetDisplay?の"Commit" and "Revert"も同じ考えです

SimpleCommand?を使用のは1つの例です。

コマンドボタンのEnableが効かないのはおかしなはず。 (for example, using 'after 0s do' or 'enqueue-event') を利用することで回避できるかもしれない。

非同期処理について

Q.重い処理中、ファイル読み込み時などにプログレスバーを表示したいのですが?

[回答]

Curlはシングルスレッドアプリのため、非同期処理を実現するには、 基本的なアプローチは処理を固まりに分けて、 処理の間にdispatch-eventをいれ、タイマーでまわすという方法が必要です。

サンプルを現在鋭意製作中です。

バリデーション

Q.基本的な画面におけるバリデーションのセットをプロパティのようにセットしたいのですか?

[回答]

複数のコントロールが並び、SUBMITボタンを押したときに、すべてのコントロールの値をチェックし、 もし正しくない値があれば、そのテキストフィールドの背景色を黄色にし、 フォーカスを当てて、何らかの形でエラーメッセージをユーザーに見せるサンプルを現在鋭意製作中・・・。

設計について

Q.Curlをつかったシステムを開発するときの取っ掛かりは?

[回答]

開発手法はプロトタイピングを推奨します。 Curlはプロトタイプが作りやすい仕様になっており、 まずは動くものを作ってしまうという 乱暴に思えるかもしれませんが、実に有効な手段です。

設計段階のポイントしては、サーバーとクライアント間の「データのフォーマット」を明確に決めことです。 これを後で変更しないことが重要になります。

Q.Curlアプリケーションを開発しようと思うのですが、どんな設計をすればいいですか?

[回答]

Curlはオブジェクト的にもスクリプト的にも記述することができますが、 設計としてはオブジェクト指向で行うのがよいでしょう。

以下に私が共通して必要だと思うクラスを挙げてみました。

最近話題にあがっているアスペクト指向については 私が不勉強のためここでは触れません。

通信について

通信をする際、サーバー側、クライアント側でそれぞれ気をつけることは?

[回答]

データ送信前に、双方で送るデータをログとして残しておく設計にすることを推奨します。 アプリケーションのバグのように見えても、 通信中にデータが欠けていたりすることがあり、データを残しておくことで、 デバッグがしやすくなります。 実運用ではログを残さないように切り替えてもよいでしょう。

リッチクライアントの開発ではクライアントとサーバーに 責任の切り分けに役立つ。

POSTデータが正しく送られていないようなのですが・・・?

[回答] 通信に関する問題が起きたら、クライアント側だけでデバッグしてても、原因が分からないことがありますので、 まずサーバーとクライアントの両方でログをとるようにしましょう。

POSTデータが欠落する問題は、wininetのバグによって発生するようです。 どうやら、wininet独自の60秒でのタイムアウトが発生するまで サーバからのkeep-alive-timeoutを無視するらしいです。

問題の解決方法はサーバのkeep-alive-timeoutの設定を60秒より 長くするのが一番簡単かと。

クライアントキャッシュの利用

Q.なるべく新しいアプリを使いたい。でも通信料は減らしたいのですが?

[回答] resync-as-of を利用しましょう。

日時の値は各パッケージの内容にもよりますが、基本的には、 「公開予定日」にしておけば、 開発中、公開後もそのまま利用できる。

↓まとめてみました。

http://www.asahi-net.or.jp/~iq7t-ummr/cache.html

パッケージ構成について

Q.複数人で開発していて、パッケージを統合したら、動かなくなってしまったのですが?

[回答]

グローバル変数を疑ってみましょう。 各ファイルで勝手なグローバル変数をトップレベルで作って、それが衝突しているのではないでしょうか。

Q.開発した部品を結合して実際にテストしたら、起動までにかなり時間がかかるようになってしまいました。どうすればいいですか?

[回答]

Curlはテキストファイルをクライアントでコンパイルするため、 includeやimportなどで起動ファイルにあまり大量のソースを結び付けてしまうと、 それらすべてをコンパイルしなければいけないために時間がかかりすぎてしまいます。

しかし、部品群を複数のパッケージにわけ、必要なときに動的にインポートするようにすることで、 オーバーヘッドの時間を減らすことができます。

これを利用して、各プログラムをパッケージとして分けて 動的インポートを利用するようにしましょう。

「動的インポート」とは、アクションなどに応じてCurlパッケージを任意のタイミングでインポートすることで、 import-packageマクロを利用します。

たとえば、検索、入力、登録というように業務が分かれている場合、 各業務で使う画面ごとにパッケージを分けておき、 コマンドボタンなどで検索業務へナビゲートされるタイミングで、 検索画面のパッケージのみをインポートする、 というような使い方になります。

そのためにも、各パッケージをなるべく細かく分けられるように設計しておきましょう。 とくに画面と画面遷移を管理するクラスの設計には気を使うべきです。 またその際にパッケージ名などの衝突をおこさないように、 パッケージやクラスの名前にも考慮をしておきましょう。

私のお勧めは、以下のような構成です。

evaluate' (or 'elaborate')を利用する方法もあります。

また、「起動時間」という点については、パッケージキャッシュを使うこと、 IDEが入っている端末では自動デバッグをしないこと、 などにも気をつけてください。

なお、あくまで個人的な目安ですが、 1つのパッケージでソースコード量が1MB、ファイル数が50を超えてたら、 「アウト」ですね。

画面作成と画面遷移について

Q.画面をどのように作ればいいですか?

[回答]

基本的には、データから自動的にプレゼンテーションを生成する仕組みを推奨します。 それはオーバーヘッドを小さくすることにも役立ちますし、 あとで、印刷オブジェクトをクローンせずに印刷できることにも役立ちます。

VLEなどで作成した画面をインスタンスかする際に、 データを引数として渡して、データの名前とコントロールの名前でマッピングを行い、 表示するときにはすべてのデータが格納された状態で画面が表示されるとよいでしょう。

このときに、画面がデータを保持するようにすると、 画面間でデータを受け渡すときに楽になります。

現在「画面作成のためのガイドライン」鋭意製作中・・・。

特権について

Q.これから作ろうとしているアプリケーションに特権がいるかわからないのですが?

[回答]

特権が必要な処理は外部リソースへの「暗黙的」な処理になります。 そういった処理を非特権アプレットが行おうとした場合、 SurgeRTEはユーザーへメッセージングしてくれる仕様になっています。 つまり、絶対にできないわけではないので、メッセージが表示されることが許容できれば、 どんなアプレットも特権は要りません。

おもな処理は、「ファイルの読み書き」、「クリップボードの利用」などです。

Q.ユーザーがたくさんいます。どうやって特権をかけさせればいいですが?

[回答]

特権はユーザーディレクトリのなかにファイルとして定義されています。 ユーザーが多くて、それぞれに設定させることが不可能な場合は、 この内容を追加上書きするアプリケーションをインストーラ作成ツールなどで、作成するのがよいでしょう。

Curl Starter Kit (CSK)について

Q.棒グラフやフロートペインを表示させたいのですが。

[回答]

Curl Starter Kit(CSK)に入っているクラスを利用してください。 CSKは、開発環境を購入するとついてきます。

内容は以下

「主要パッケージ」

●チャート

円グラフ、棒グラフ、線グラフ、エリアグラフなどが作成可能。

●DB関連

ADOとつないだり、CSVファイルDBライクに使えたりする。

●ツリーコントロール

階層構造を表現するコントロールを作成可能。

●ポータルペイン

入れ替えたり、自在に動かすことの出来るウィンドウを作成可能。

●IPC

アプレット間通信を利用可能

「主要サンプル」

Program Files\Curl Corporation\Surge\CSK304\extras\csk-extras-viewer.curl

●各種ユーティリティ

CALCULATOR

CALENDAR

CLOCK

COLOR-CHOOSER

EXPANDING-MENU

SIMPLE-SLIDER

●階層構造表現

HIERARCHY-BROWSER

●XHTML

MINI-XHTML

●チャート

SIMPLE-GRAPH

BAR-CHART-3D

STOCK-CHART

●2D表現

SHAPED-BUTTONS

FILTERS

FIRE

FLAG

FRACTAL

WATER-PICTURE

LOGO-3D

●3D表現

GLOBE

LIT-BUTTONS

TEAPOT-3D

MOLECULES

●画像ビューワ

PHOTO-BROWSER

SLIDE-SHOW-TRANSITIONS

SLIDE-SHOW-LUMA

WEBサービスについて

Q.WEBサービスを作成したので、Curlで使いたいのですが?

[回答]

Web Service Developer Kit(wsdk)というものが開発中とか。

CURL社に問い合わせてみてください。

Curlの標準仕様について

Q.検索ダイアログや右クリックメニューを表示したくないのですが?

[回答]

梅村の「口」のCurlコンテンツにある「CURLサンプル置場」の 2005年3月14日と16日を見てください。

梅村の「口」は→ http://www.asahi-net.or.jp/~iq7t-ummr/

Visual Layuout Editorについて

:Q.VLEに部品を簡単に追加したいのですが?

[回答]

ヴァージョン4から、部品用追加ツールが用意されるそうです。

翻訳ファイルについて

Q.VLEのプロパティ名を英語にしたいのですが?

[回答]

まず、翻訳ファイルを変更します。 [C:\Program Files\Curl Corporation\Surge\4\designer\curl-resources\ja]にある、 翻訳ファイル[translations.xml]を開きます。

<key>prop-name:***</key>というタグが、VLEでプロパティ名を翻訳するための部分ですので、 そこをごっそりコメントアウトします。 2400行目あたりから、3300行目あたりぐらいです。 (<!-- コメントアウト-->)

次に、すでに作られたVLEのキャッシュを消します。 コントロールパネルから[キャッシュ設定]で、キャッシュを空にしてください。 [C:\Documents and Settings\ユーザー名\Local Settings\Application Data\Curl Corporation\Surge\package-cache\4]の なかのファイルを[cache-state.scurl]以外消えていることを確かめてください。

最後に、Surgeを再起動してください。

これで、VLEを立ち上げたら、プロパティ名は英語になっています。

テーブルについて

Q.テーブルのセルの枠線がうまくひけないのですが?

[回答]

表形式の表現には、可能な限り、RecordGrid?を利用するのが望ましいです。 セルや行ごとの背景色変更など、難しい部分もありますが、 それらは今後改善されていくことでしょう。

それでも、諸事情でTableクラスを使いたい、という場合は、 http://www.asahi-net.or.jp/~iq7t-ummr/ のCurlサンプル置き場の2005/3/20のものを参考にできます。

Crulカッコ({})について

Q.Crulカッコ({})の使いどころがわからないのですが?

[回答]

{}の意味を理解し、利用は必要最小限にとどめることを推奨します。

Curl言語では{}を使うことで、その中の文字列がコマンドとして認識される、 という使用になっています。 そのため、Curlファイルの中で、アプレット宣言文の後にそのまま {let a:int = 300} と記述すると、300という値のaという変数がインテジャー型で 宣言されることになります。 これを「トップレベルで変数を宣言する」といいます。 トップレベルで宣言した変数は、アプレット全体にスコープを持つ、グローバル変数となります。

一方、{}を使わずに記述すると、Curlはコマンドとは認識せず、 そのまま文字列としてブラウザに表示します。 HTMLをご存知の方にはむしろ理解しやすいかもしれません。

さらに、valueなどのブロックの中ではlet文を使わなくても変数を宣言できます。 これは「value文のカッコの中」という判断がされるためで、 同時に、スコープもvalue文の中だけとなります。 コンストラクタやプロシージャなどの中でもおなじルールが適用されます。

もちろんvalueブロックの中でlet文に{}をつけてもよいのですが、 IDEを使う際、作成したプロジェクトのなかのクラスやプロシージャの一覧が見れる、 定義ペインというものがあり、 その中で、{let}はすべてグローバル変数として認識されてしまうため、 なるべく使わなくてもよいカッコはつけないことを推奨します。

また、doステートメントを有効に使いましょう。 valueの場合には、「最後に指定した変数」が画面上に表示される (正しくは「戻り値として返却された形式に応じて解釈され、表示される」)のですが、 doステートメントの場合は画面上に表示されません。

ですので、popup-messageなどの戻り値が有るプロシージャやメソッドを、 処理だけに利用したい場合には このdoステートメントを使うことをお勧めします。

Streamについて

Q.Streamの扱いで気をつけることはありますか?

[回答]

Streamをクラス間、プロシージャ間で受け渡すことは避けましょう。

Curlに限りませんが、Streamは通常、作成、開く、読く・書く、閉じるの4ステップを踏みます。 とくに閉じることが重要なのですが、 このステップの途中でstreamを受け渡すと、その後、streamを閉じる判断が難しくなるだけでなく、 streamの中身が空になっているような場合、デバッグでそれを見つけることが困難になります。

できれば、設計する際は、Input、Output両方について、Streamを作る部分を、 アプレット全体で一つに決めるべきです。

とくにHTTP通信を利用する際に行いやすい誤りとして、 1つのホストへリクエストに対するレスポンスが帰る前に別のリクエストを送ってしまうと、 ホストオープンエラーが発生しますが、 Streamのコードを分散させないことで、これを制御しやすくなります。

通常、Streamを作成する際は、IOの例外を取得するために、 try-catchの中で作成します。 その場合はfinally句のなかで必ずStreamをクローズするようにしてください。

http://www.asahi-net.or.jp/~iq7t-ummr/ のCurlサンプル置き場の2005/08/09のものを参考にしてください。

nullの利用について

Q.どのようにnullを使えばよいのですか?

[回答]

Curlはnullの扱いに優れた言語です。 型の最初に'#'をつけるだけでその型とnullを許すことができます。 (例: let str:#String = null)

しかし、使いやすいからといって、なんにでもnullを許すべきではありません。 nullを許すことで、そのあとの制御が難解になったり、 コード量が増えてしまうことがあるからです。

nullを許すということは、ある変数の値が、入っているか入っていないか、 という判断を必ずしなければならなくなります。

Curlの仕様上も、配列などをfor-in文でコンテナとして繰り返し処理する場合には、 nullを許さない型の変数に一度格納する必要があります。 null値の可能性があるコンテナでの繰り返し処理を禁じているからです。

このときのテクニックとして、if-non-nullを利用する方法があります。 if-non-null区で判断された変数は、そのブロック内では定数として処理されるため、 型がnullを許していても繰り返し処理などが可能になります。 ただしこれは、クラスのフィールドなどには使えず、単体の変数のみに有効です。

多くの場合、nullを、正しい設計でないコードの処理を通すために使う傾向があります。 しかし、そういったつぎはぎのコーディングはさらに大きな問題をひきおこします。 nullになった場合は例外として処理する、初期値を用意するなどの方法を使って、 必要なnull以外は利用しないコードを目指しましょう。

盲点として、コンストラクタなどで値をいれるためのフィールドなどには、 コンストラクタのブロックが終了するまでに値が入ればよいです。 (例: {define-class Class

   field private _date:DateTime
   field public  number:int
   {constructor public {default number:int}
	set self.number = number
	set self._date = {DateTime}
   }

運用について

Q.Curlを実際に運用する際に必要なものはなんですか?

[回答]

CurlはWEB上で利用されることを前提にしていますので、 アプリケーションを配置するためのWEBサーバーがまず必要です。 さらに、そのWEBサーバーにCurlアプリケーションを配置することを 許すためのライセンスファイルを置く必要があります。 このライセンスファイルは有料で、 配置用WEBサーバーのURLと一緒にCurl社に申請すると発行されます。

このライセンスファイルはWEBルートか、 Curlアプリケーションと同フォルダのどちらかに置いてください。

Curlアプリケーションの実体はソースコード、 もしくはコードを圧縮したファイルですので、 実際に配置する方法は、単純にフォルダに保存するだけです。 Curlの開発環境を利用すると配置を自動的に行ってくれます。

最後に、このCurlアプリケーションがWEBサイトのリソースへの アクセスを設定するファイル「curl-access.txt」を、 WEBルートか、アクセスする全てのリソースと同フォルダに置く必要があります。 これはサーブレットやCurlのソースコードなど全てが対象です。

その他、場合によってはCurlのソースコードを認識させるために WEBサーバーのMIMEタイプなども設定する必要もあります。

Curl開発環境のオンラインヘルプの、 「WEBサーバーの構成」の項に詳しい説明があります。

コメントのつけかたについて

Q.コメントをつける際に注意する点はありますか?

[回答] Curlでは以下のコメント方式を採用しています。 一行コメント  || comment-text 複数行コメント |tag-name# comment-text #tag-name| (tag-nameは省略可)

またCurlの開発環境ではF8キー、Shift+F8キーによって 選択行をコメントイン、コメントアウトすることができます。 その際には行頭に"||--"というコメント文字が挿入されますが、 誤ってF8キーを押してしまった場合などのエラーに備え、 このコメント方式はあくまでもコーディング中での テンポラリな作業にのみ使うべきでしょう。