LoginSignup
1
1

More than 5 years have passed since last update.

RubyのHashの落とし穴?

Last updated at Posted at 2016-08-13

Rubyの配列とHashを使っていて個人的にハマったのでメモ。
Hashの配列を作り、それをHashで扱うときがありましたが、Array.newで初期化してから値の変更をしようとすると全てのkeyの値が変わってしまいました。

# これはダメ
temp = {}
init = {:a => 0, :b => 0}
temp[:aaa] = Array.new(2, init)

p temp

# 値を代入
temp[:aaa][0][:a] = 1

p temp






# これはOK
temp = {}
temp[:aaa] = [
  {
    :a => 0,
    :b => 0
  },
  {
    :a => 0,
    :b => 0
  }
]

p temp

# 値を代入
temp[:aaa][0][:a] = 1

p temp

結果

{:aaa=>[{:a=>0, :b=>0}, {:a=>0, :b=>0}]}
{:aaa=>[{:a=>1, :b=>0}, {:a=>1, :b=>0}]}
{:aaa=>[{:a=>0, :b=>0}, {:a=>0, :b=>0}]}
{:aaa=>[{:a=>1, :b=>0}, {:a=>0, :b=>0}]}

(追記)
原因はこれ。
http://simanman.hatenablog.com/entry/2013/06/24/200306
初期化の仕方に問題があるみたいです。
最初の初期化で別々の配列オブジェクトを定義したつもりが、実は全て同じ配列オブジェクトを参照しているらしいですね。

ちなみに
temp[:aaa] = Array.new(2, init)
ここの部分ですが、
temp[:aaa] = Array.new(2).map{Hash.new}
のように初期化しないとダメでした。

1
1
1

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
1