配列応用レベル

次のプログラムを実行すると何が表示されますか?

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 などを検討します。

問題一覧へ戻る