RGSS2を知る(21)
次はTableクラス。
Cで書いた拡張ライブラリからアクセスするぶんには、Arrayの内部構造でも別に遅くはないが、Rubyから3次元配列にアクセスしようとすると、1アクセスごとにメソッド呼び出しが3回となって、さすがにちょっとしょんぼりだ。
Arrayの[]を再定義するわけにもいかないから、このようなクラスがあるのは悪くない。
t = Table.new(2,2,2) open("c:\\test.txt","w") do |fh| for z in 0...t.zsize for y in 0...t.ysize for x in 0...t.xsize fh.write "[#{x},#{y},#{z}] = #{t[x,y,z]}\n" end end end end
[0,0,0] = 0 [1,0,0] = 0 [0,1,0] = 0 [1,1,0] = 0 [0,0,1] = 0 [1,0,1] = 0 [0,1,1] = 0 [1,1,1] = 0
とりあえず初期値は0。マニュアルに書いてないんだもの。
んでもって省略した次元は1。
p Table.new(1).zsize #=> 1
さて、このような普通のクラスをなぜここで取り上げるのかというと、マニュアルにこのような記述があるからだ。
要素数が 0 の配列を生成することも可能です。
えーっと・・・??????
意味がわからん。
3次元の箱を想像して、そのうちの1辺の長さが0になるようなものだろう。それはもう3次元の物体として存在できないものになっていて、つまり3次元のうちどれか1つが要素数0になった時点で、Tableオブジェクトの中身は空っぽになるのではなかろうか。
t = Table.new(2,0,2) p t[0,0,0] #=> nil
そりゃそうだ。
この仕様の存在意義がわからないが、このように実装しないといけないのだろうか。
こんなんエラーでいいやん?それともなんか有意義な使い道が?
最後にちょっと長いがresizeの結果を。
def output(t, type) open("c:\\test.txt",type) do |fh| for z in 0...t.zsize for y in 0...t.ysize for x in 0...t.xsize fh.write "[#{x},#{y},#{z}] = #{t[x,y,z]}\n" end end end fh.write "\n" end end t = Table.new(2,2,2) t[1,1,1] = 1 output(t, "w") t.resize(3,2,2) output(t, "a") t.resize(1,2,2) output(t, "a") t.resize(2,2,2) output(t, "a")
[0,0,0] = 0 [1,0,0] = 0 [0,1,0] = 0 [1,1,0] = 0 [0,0,1] = 0 [1,0,1] = 0 [0,1,1] = 0 [1,1,1] = 1 [0,0,0] = 0 [1,0,0] = 0 [2,0,0] = 0 [0,1,0] = 0 [1,1,0] = 0 [2,1,0] = 0 [0,0,1] = 0 [1,0,1] = 0 [2,0,1] = 0 [0,1,1] = 0 [1,1,1] = 1 [2,1,1] = 0 [0,0,0] = 0 [0,1,0] = 0 [0,0,1] = 0 [0,1,1] = 0 [0,0,0] = 0 [1,0,0] = 0 [0,1,0] = 0 [1,1,0] = 0 [0,0,1] = 0 [1,0,1] = 0 [0,1,1] = 0 [1,1,1] = 0
大きくすると中身は保存されるが、小さくしてから戻すと消える。
これはまあ、普通だ。
Cの多次元short配列だと仮定すると単純にreallocするわけにはいかないから、mallocしてそのようにコピーしているのだろう。
あ、これほんとに最後。
t = Table.new(1,1,1) t[0,0,0] = 60000 p t[0,0,0] # => -5536
飽和はしないらしい。