配列応用レベル
次のプログラムを実行すると何が表示されますか?
DEFAULT_CHARGES = [ { name: "basic", tags: ["default"] } ] charges = DEFAULT_CHARGES.map(&:dup) charges[0][:tags] << "paid" p DEFAULT_CHARGES
- 1[{:name=>"basic", :tags=>["default"]}]
- 2[{:name=>"basic", :tags=>["default", "paid"]}]
- 3[]
- 4FrozenError が発生する
解説
map(&:dup) により、外側の配列と中のハッシュは別オブジェクトになります。しかし dup は浅いコピーなので、ハッシュの値として入っている tags 配列までは複製されません。charges[0][:tags] と DEFAULT_CHARGES[0][:tags] は同じ配列を参照しているため、<< "paid" の変更が DEFAULT_CHARGES 側にも見えます。入れ子の変更まで独立させたい場合は、設計を見直すか、Railsなら deep_dup などを検討します。