rubyのお勉強中、次のような配列がほしいとなりました。
[[true, false, false, false], [false, false, false, false], [false, false, false, false], [false, false, false, false]]
正方形の左端だけがtrue、残りは全部falseというイメージ。
簡単そうですね。
ちゃっちゃと書いてしまいましょう。
ary = Array.new(4,Array.new(4,false)) ary[0][0] = true
できたできた……と満足していたのもつかの間、何かがおかしい。
いろいろ調べてみたところ、次のようなことがわかりました。
ary = Array.new(4,Array.new(4,false)) ary[0][0] = true p ary #=> [[true, false, false, false], # [true, false, false, false], # [true, false, false, false], # [true, false, false, false]]
「何か、思っていたのと違う?」と思い、慌ててArrayのクラスメソッドnewの使い方を確認したところ、次のような記述を発見してしまったという次第です。
長さ size の配列を生成し、各要素を val で初期化して返します。
要素毎に val が複製されるわけではないことに注意してください。 全要素が同じオブジェクト val を参照します。
これは知りませんでした。
ちなみにほかの例でも同じようなことが起こります。
hashs = Array.new(4,Hash.new) hashs[0][:name] = "nekoTheShadow" p hashs
としたとき、一見すると次のような結果が得られるような気がします。
[{:name=>"nekoTheShadow"}, {}, {}, {}]
しかし、実際にはこうなるわけです。
[{:name=>"nekoTheShadow"}, {:name=>"nekoTheShadow"}, {:name=>"nekoTheShadow"}, {:name=>"nekoTheShadow"}]
それにしても日々不勉強が明らかになりますね。
頑張らねば。