0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 1 year has passed since last update.

【Ruby】コピー時に元データがなぜか上書きされる【浅いコピー】

Last updated at Posted at 2021-12-25

コピー先の変数の値を書き換えようとしたら、なぜか、コピー元の方まで値が書き変わってしまう謎現象に遭遇し、困ったのでメモ。

謎現象の原因を探るには「浅いコピー」「深いコピー」「参照渡し」という概念について、それぞれ理解しなきゃならないらしい。

なんでお前が書き換わんだよ!!!お前じゃないんだよ!!!!
と3時間ぐらい一人で格闘していたが、
浅かったのは、私の頭の方だった。

浅い頭を悩ませる「浅いコピー」

【Ruby】コピー時になぜか上書きされてしまう【参照コピー、浅いコピー】.jpg

浅いコピーというのは、コピー元のオブジェクトとコピー先のオブジェクトがメモリ上の同一の場所を参照することになります。

っておい、なんじゃそれ :rage:

どうやら、参照先は一緒になるので、
片方に変更を加えると、もう片方のデータも変わってしまうらしい、と。

追記)cloneメソッドなどの浅いコピーは、
配列などの多次元配列の際意図しない挙動になることがあるようです。

これは落とし穴…。

配列の参照渡し

あと、配列の参照渡しなるものも気をつけなきゃいけないらしい。
(※追記.Rubyは厳密には配列の参照渡しではなく、参照の値渡しだそう)

A=BでBをコピーできるのかと思っていたが、そうじゃないらしい。

# 配列データを準備
$ origin = ["書き換え前"]
=> ["書き換え前"]

# コピーするよ!!
$ copy = origin
=> ["書き換え前"]

# コピーした(はずの)配列を書き換えてみる
$ copy[0] = "書き換えたよ!!!!"
=> "書き換えたよ!!!!"

# ↓なんでだよ!!!(なぜか元データが変わってる)
$ origin
=> ["書き換えたよ!!!!"]

# オブジェクトIDを比較してみる
$ origin.object_id
=> 440

# あれ?オブジェクトIDが一緒...?コピーできてないっぽい
$ copy.object_id
=> 440

そもそもA=BでBはコピーできないらしい。
オブジェクト名は違うが、結局同じ住所を見ているから、だと。

勉強になったよ。

参考

詳細は、こちらが 参考 になるかと。

【Ruby】コピー時に元データがなぜか上書きされる【浅いコピー】

2021.12.25 追記)
ご指摘頂いた箇所を一部修正いたしました。

0
0
9

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
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?