Rb2007の継承が、ちょっと変だ
実例
- ModuleAを作成
- ModuleA.ClassAを作成
- ModuleA.ClassAにコンストラクタ"Sub Constructor()"を宣言(中身は空でok)
- ModuleBを作成
すると、ModuleB.ClassBにコンストラクタの中身がRbによって自動的に補完されます。
スーパークラスのコンストラクタを忘れずに呼びましょう、といっているようです。
このおせっかいサポートはRb2006の頃からずっとなので、別に問題はないのですが、
なんというか、これが、そのままだと動きません。
ビルドすると→
「そんなメソッド知りませんが?」とかいわれる。
そのコード書いたの、私じゃないんだけど
要するに
RbのSuperの実装が、バグッテル
回避法
キーワードSuperをやめて、ModuleA.ClassA.Constructorって書けは、
一応回避はできます。
うーん..めんどうだねぇ
なんとかして><
Intel入ってみたので、絵箱の猫はカラーにしてみる
絵箱は猫がポイントなのですが、この猫が「やたら口が大きい」と時々言われます。
確かに...
そんなわけでカラー化をもくろんでみました。
次のバージョンは4にしようと思っていたのです。
でも、よくよく考えたらそんなに機能的な進化点は
ないから、自重してver3.5にしようかと思い直し中。
ここへ来て、絵箱が条件によって不安定になる原因を
一つ見つけてしまったので、少し抜本的な構造改革を
してから出そうと思います。
一応予定している変更点
- Intel対応
- ユニバーサルバイナリなのでPPCでも動きます
- 平均すると大体3〜4割くらいの高速化です
- Spotlight検索
- アイコンがカラーに
- 大量ファイル一覧時のメモリ使用量をまともに
- サムネイルさえついていれば実消費メモリは40MB位で動きます
- 安定性向上
- その他細かいの色々
もし要望があれば
コメント等でお願いします。
REALbasicのCancelCloseとかDesutructorとかまとめてみた
Rbを普通に使っていると、後片付けのことをほとんど気にしなくてよいのだけど、
色々付け足して、終了時に設定保存したり、「本当に終わっちゃっていいの?」って
聞いたりしていると、たまに動作が不安定になることがあるのです。
というか、今の絵箱(ver3.2.1)がそれ。
たまに、終了時にエラーはいたりするのです。
というわけで、整理!
REALbasicのいろんな後片付けイベントの呼び出し順をまとめてみました。
使ったのはREALbasic2007r4。
準備
順番を調べるもの :
- Appオブジェクト
- CancelCloseイベント
- Closeイベント
- Destructor*1
- Windowオブジェクト
- CancelCloseイベント
- Closeイベント
- Destructor*2
- Appにプロパティとしてセットしたオブジェクト*3
- Destructor
- Windowにプロパティとしてセットしたオブジェクト*4
これら7個のイベント、メソッドの呼ばれる順番を調べます。
結果
- App.CancelClose
- MyWindow.CancelClose
- MyWindow.Close
- MyObjOnWindow.Destructor(::MyClass)
- MyWindow.Destructor
- App.Close
- App.Destructor
- MyObjOnApp.Destructor(::MyClass)
考察
基本は当たり前に「参照する側」→「参照される側」の順番で解放される。
でも、Windowはちょっと特別扱い*5。
WindowはApplicationクラスからは(REALbasic的には)参照されていない。
だったらどうなの?
のはずが、死んだAppにアクセスできる!
なぜかApp.Destructorが終了した後も、Appにはアクセスできる...
これってありなの??
*1:Destructorの呼び出しを検出するために、このAppはApplicationクラスの直下サブクラスではなく、Application継承のカスタムクラスのインスタンスにする
*2:これも*1のAppと同じ
*3:Objectの直継承
*4:これもObjectの直継承
*5:マニュアルにも記載があるし、確かにそうあるのが好都合なのだけど、合理的な説明は思いつきません
*6:この「操作」のためにWindowの参照を保持しておけば、Window.Destructorの実行は延期される。けど、既にCloseしてしまっていることには変わりないので、下手に触るとNilObjectExceptionか、最悪無言で落ちるようです。
円グラフすら描けなかったのか
ということに今更改めて気づいた。
なんでかREALbasicは円弧を描けない。
円弧なんてQuickDrawの時代から当然のように描けたはずなのに
仕方がないから、作ってみました。
使い方
- サンプル見てください。簡単です
- メソッドはDrawArc , FillArcの二つだけ
- 実体はRb標準のDrawPolygonです。ので、あんまり速くないです。
- 実装がしょぼいので、誰か手直ししてください
- 縦横比が微妙なとき、線が汚いかも。どっかで誤差してる??
って後半使い方じゃないし。
改変自由の著作権表示も強制しないぬるいライセンスにしときました。
別にライセンスとかどうでもいいんだけどね
折角だからExtendsキーワードを使いたかった。
GraphicsExtension.DrawArc Window.Graphics,0,0,100,100,30,120でもいいけどさ、
Window.Graphics.DrawArc 0,0,100,100,30,120 って描けたら、すごくいい。
GraphicsはExtendsできなかった...
そっか、Graphicsは抽象クラスだった。
Extendsはインスタンスとメソッドを擬似的にリンクさせる文法糖だから、抽象クラスには使えないわけです。
その理屈は、わかる
わかるけど
Rbが隠蔽しちゃって、Graphicsサブクラスの本当の名前がわからない...
むー...
絵箱をUnversalBinaryしてみるテスト
今更ですか、REALbasicが直販になったので、「REALbasic 2007 Release 2」を入れてみる。
とりあえずトライアルモードで。
早速比べてみよう。使うのは
- 絵箱3.2.1PPC
- 今公開しているバージョン。Rb2006r3でビルド
- 絵箱3.2.1Intel
- そのままRb2007r2でひらいて、UniversalBinaryとしてビルドし直したもの
の二つ。MacはiMac2.16GHz Intel Core2 Duo、メモリ1GB
TEST1 サムネイル作成速度
TEST2 画像表示
準備
- iMac(OS10.4)付属のデスクトップピクチャ「Nature」フォルダを開く
- 14枚の画像(2560*1600ピクセル)をすべて選択
TEST3 画像処理(RbScriptによる演算)
準備
- iMac(OS10.4)付属のデスクトップピクチャ「Nature」からクマノミの写真2560*1600ピクセル)を開く
- 「画像」メニューから「プラグイン」>「なみ」を開く
- 設定値を「波の高さ=60,波の周期=20」にする
結論
大体30%前後の高速化。体感的にもそのくらい。
なにも修正してないのに、結構早いよ。
あと、
バグが幾つか直ってた。
ということは
買いでしょうか?
Dictionaryをシリアライズしてみる
やっぱりシリアライズは鬼門?
どうもRbユーザの結構な数が、データのシリアライズに苦労しているみたい。
Key=Value形式のテキストで保存して、改行のエスケープ忘れてファイル壊しているような人もいるし...
初心者さんにやさしいはずのREALbasicがこんなことでいいのかなぁ
作ってみた
ちょうど必要だったから、作ってみた。
Dictionaryを丸ごとファイルに書き込みます。
数値系、文字列、色、日付、真偽、とDictionay。
入れ子になったDictionaryを型や構造を保ったまま、まとめて一気に保存できるので便利。
MemoryBlock使ってるから、まあそこそこの速さです。
もともと絵箱で使ってたコードをきちんとクラスにしただけだけど。
使ってみた
Dictionary継承だから、使い方も簡単
Sub App.Open
//新しいファイル作成。既存なら自動的に読み込み
Dim Pref as NekoDictionaryFile(DesktopFolder.Child("MySetting.pref"))
//後は普通のDictionay
//Pref.Value("foo") = "bar"とかご自由に
//保存
Pref.Save
End Sub
Dictionaryも保存できるよ。
たとえば、追記型日記帳。
Dim Diary as NekoDictionaryFile
Dim Dict as Dictionary
Dim D as Date
//日記帳を開く。なければ作る
Diary = New NekoDictionaryFile(DesktopFolder.Child("日記帳"))
//空なら初期値設定
If Diary.Count = 0 Then
Diary.Value("Title") = "ユキの日記帳"
Diary.Value("TopPage") = "http://hatena.ne.jp/Mattsun/"
Diary.Value("Contents") = New Dictionary
End If
Dict = Dictionary(Diary.Value("Contents"))
//今日の日記を追加
Dict.Value(new Date) = "http://hatena.ne.jp/Mattsun/20070512" //今日の
//保存
Diary.Save
感想
意外と感動した。ファイルとDictionaryが一対一に対応してるとなんとなく安心感。
いやむしろ、この程度で感動できるREALbasicに感動した。
ダウンロード
http://nekobooks.com/tools/nekodict/NekoDict.zip
- 細かいことはソース読んで下さい。
- ライセンスとかどうでもいいので、好きに使ってください。
- Rb200X対応でちょっと手を入れたのでバグ混入してるかも。自己責任で
- Rb2006以降 Mac/Win両対応。圧縮はWinでしてます