スタックを保存する

 HyperCard の特長のひとつに「データをどんどん貯め込むことが出来る」というものがありました。スタックに書き込んだテキストは自動的に保存され、新しく作ったカードやボタン、ペイントの状態なども全てスタックファイルに書き込まれます。ディスクアクセスが頻繁に起こることでスピード低下の原因にもなっていましたが、手軽な開発環境としては理想的な構造だったと思います。

 一方で、ほとんどの開発環境で作ったアプリケーションは、アプリケーションの変更をアプリケーション自身のファイルに保存出来ません。例えば REALbasic で作ったアプリケーションは、起動中にボタンの項目名を変更することは出来ますが、次回起動すると元に戻ってしまいます。変更した状態を再現するには、プレファランスファイルなどにその情報を書き込んでおいて、次回起動時にそれを参考にしてボタン名などを書き換えねばなりません。 HyperCard に慣れた身にはこれはかなり面倒です。

 また Unix や Windows では、OS の仕組みとして、起動中のアプリケーションが自分自身を書き換えることは出来ません。これらの OS 上で HyperCard (で作ったアプリケーション)のような快適さを実現するのは、そもそも無理なのです。 RunRev はマルチプラットホームの開発環境であるため、MacOS にも Unix や Windows と同じ制限を課しています。つまり RunRev で作ったアプリケーションは、その変更をディスクに保存出来ません。新しく作ったボタンも、新しく作ったカードも、一切ディスクに保存することは出来ないのです。

 ただし、これは「アプリケーションとしてビルドしたスタック」に対する制限です。スタックそのものは save 命令でディスクに保存することが出来ます。 RunRev ではアプリケーションの変更を保存出来ないという欠点を補うために、いくつかの方法が用意されています。 HyperCard や SuperCard ほどには簡単に扱うことは出来ませんが、それでも充分現実的な手段になり得ています。それを解説してみましょう。


1)スタックのまま使う(アプリケーションとしてビルドしない)

 スタックをスタックのまま配布する方法です。ユーザーは自分のパソコンに RunRev をインストールします。インストールされた RunRev は、一種のプレイヤーとして働きます。

 RunRev 1.x では、スタックをダブルクリックして RunRev を起動すると、いくつかの不具合が出ていました。恐らく RunRev をサーバサイドの CGI 環境として使えるように、起動を速めるための措置だったと思われます。GUI の一部が正常に機能しない状態で起動していたのです。 1.x で単独配布出来るスタックを作るには、Distribution Builder の機能を利用して、必要なライブラリをスタックファイルの中に組み込む必要があります。

 RunRev 2.x ではこの制限が無くなり、スタックのダブルクリックで RunRev を起動した場合でも、フル機能を使えるようになりました。このため、RunRev の持っているライブラリをスタック中に組み込む必要はありません。

 アプリケーションとして作ってしまうと保存が利かないのであれば、スタックのまま使ってしまおうという方法です。作成時と同じ環境でスタックを使うわけですから、全ての変更が保存可能です。

 ただし、ユーザーからは RunRev のメニューやパレットが丸見えです。意図しない改変が行われる可能性もありますし、ユーザーがある程度 RunRev の扱いに習熟している必要があります。 RunRev ユーザー向けならともかく、一般の不特定ユーザーに使って貰うスタックには、この方法は向かないでしょう。


2)プレファランスファイルに変更を保存する

 REALbasic や CodeWarrior などで作られたアプリケーションで一般的に行われる方法です。ユーザーが入力したデータや変更した内容などを、アプリケーション終了時などに全て別ファイルに保存します。そして次回アプリケーションを起動した時に、そのファイルを読み込んで前回の変更を反映させます。

 ファイルの保存先は specialFolderPath() 関数で得た「初期設定フォルダ」が一般的でしょう。ファイル内にどのようなフォーマットでデータを記録するかは、スクリプター次第です。一番簡単なのは項目ごとに行で分けて、テキストで読み書きすることでしょう。

 この方法の問題は、RunRev 独自のデータを保存しづらいことです。例えばユーザーが新規カードを作った場合に、「カードを」プレファランスファイルに保存することは出来ません。カード内のテキストデータなどを保存することは出来ますが、スタックをそのまま保存する時のような簡潔さはありません。


3)保存するスタックを別ファイルに分ける

 RunRev はひとつのスタックファイル中に、複数のスタックを入れることが出来ます。これらのスタックは全てひとつのアプリケーションファイル内に入ります。こうすることによって、複数のウィンドウを持つアプリケーションを、ひとつのファイルで実現することが出来るわけです。

 ところがこうして出来上がったアプリケーションは、スタックを保存することが出来ません。ならば。メインスタックだけをアプリケーションにして、他のスタックはスタックのまま使ったらどうだろうかというアイディアが浮かびます。

 つまりアプリケーションとして作るのは初期画面とかメイン画面の部分だけにして、状態を保存したいスタックはスタックのままアプリケーションと一緒に配布するわけです。 RunRev はこの方法をちゃんとサポートしています。

 Distribution Builder の Move substacks into individual file チェックボックスをチェックしてアプリケーションをビルドすると、アプリケーションと同じ階層にフォルダがひとつ作られます。そしてサブスタックは全てそのフォルダ内に収められます。サブスタックにはいわゆる「パスが通っている」状態で、メインスタックからは(パスを省略して)スタック名だけで呼ぶことが出来ます。

 この方法で作られたアプリケーションを起動すると、まずメインスタックが開きます。ここから go stack "myStack" などを実行するだけで、サブスタックを開くことが出来ます。そしてサブスタックの変更は save this satack 命令一発でディスクに書き込まれます。( HyperCard と違って、save 命令を実行しない限りディスクに保存されません。これをうまく使って Undo を実装することも出来ます)
 サブスタックからメインスタックを呼びたい時は、go stack ( the mainStack of this stack ) で可能です。メインスタック内のフィールドも fld xx of stack the mainStack of this stack のようにして参照することが出来ます。

 メインスタックをロゴ表示などに使えばスマートでしょう。必ずメインとサブの2つのスタックが必要になってしまうことと、ユーザーからサブスタックファイルが丸見えになってしまうのが欠点でしょうか。 OS X では「パッケージ」形式で配布すればスマートかも知れません。

 RunRev 2.0/2.0.1 を OS X で使った場合、日本語のフォルダ名をうまく認識できないという問題があります。そのためサブスタックを別ファイルに書き出す設定にした場合、メインスタックからサブスタックを探せなくなることがあります。おそらく Unicode 絡みのバグだと思われますが、これはバグフィックスを待つしかありません。


4)サブスタックをテンプレートとして利用する

 RunRev 独特の使い方として、サブスタックをテンプレートとして利用する方法があります。これは他の開発環境には無い、ちょっと面白い発想だと思います。

 まず3と同じ方法でサブスタックを用意します。そしてユーザーが「新規ドキュメント」メニューを実行した時に、サブスタックを開ます。ここからが面白いのですが、保存する時にそのまま save するのではなく、save ... as <filePath> として、スタックを別の場所に新規保存します。つまりこのサブスタックはスタックのテンプレートとして働くわけです。

 ドキュメントスタックの保存場所はユーザーに決めさせるのではなく、メインスタック(アプリケーション)のあるフォルダ下の特定のフォルダに固定する方が良いでしょう。保存したスタックをダブルクリックで開くと( RunRev アプリケーションが起動して)単独のスタックとして機能しますが、このスタックからメインスタックを探す方法はありません。ドキュメントスタックの保存場所を予め決めておけば、そのパスからメインスタックを探せるようになりますし、メインスタックからもドキュメントスタックを簡単に探せるようになります。

2003.07.29
UDI

inserted by FC2 system