PBM の画像データを 2 重配列で 受けて, 処理しようと思いました. 2 重配列の初期化はどうやろうと考えて, 最初に思いついたのが, これ.
ar = Array.new(4, Array.new(0, 4))
4 x 4 の配列を 0 で初期化したつもり. 1 行で書けて, スマート :-) で も, その後にいろいろ処理して, できた画像を見てみると, 何か変 (T_T) 例 えば…
$ irb irb(main):001:0> ar = Array.new(4, Array.new(4, 0)) # initialization [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] irb(main):002:0> ar[1][1] = 2 # substitution 2 irb(main):003:0> p ar [[0, 2, 0, 0], [0, 2, 0, 0], [0, 2, 0, 0], [0, 2, 0, 0]] # ?? nil
というように, ar[1][1] = 2
によって ar[1]
という配列しか変更していないつもりなのに, 全部の配列が同じように変化し
ています.
しばらく理由がわからなかった (^^; のですが, 答えは
Ruby FAQ
2.12 にありました. つまり, 配列 ar
の全ての要素は, 同一オ
ブジェクト (Array.new(4, 0)
) を指しているので, 1 つの要素
に対する操作でも, 全ての要素にその影響が出ているように見えてしまいます.
これを回避するには, 配列 ar
の全ての要素が互いに異なる
配列を指すように初期化する. 例えば…
$ irb irb(main):001:0> ar = Array.new(4).collect { Array.new(4, 0) } # init [[0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] irb(main):002:0> ar[1][1] = 2 2 irb(main):003:0> p ar [[0, 0, 0, 0], [0, 2, 0, 0], [0, 0, 0, 0], [0, 0, 0, 0]] # seems good nil
でも用途によっては
mdarray
を使うほうが,
はるかに楽. 初期化のときに指定した範囲の外へアクセスすると, 例外にして
くれますし.
おたより, お待ちしています
Copyright (C) 2000 Masahiro SATO