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 5 years have passed since last update.

Rubyで簡単!参照の値渡し

Last updated at Posted at 2020-09-18

祝 初投稿🎉
自分が理解する上で一番悩んだ参照の値渡しを
できるだけ噛み砕いてイメージで説明してみた。

ずれてる!
違う!
等あれば感想でご指摘いただくようお願いします。

この話はshallow copyやdeep copyの話に繋がるため、
rubyを操る上では大事。

参照の値渡しとは?

簡単に言ってしまえば、
引数で使うメモリ位置(<0x00000001>とか)らしきものを値で渡しちまおうぜ!
っていうような考え方。
とりあえずはメモリ位置の認識でいいかも。

〜渡し
っていうのは引数同士のコピーで起こる動作をそれっぽく言ったものとして掴んでおけばOK
そんなメモリ位置に入らねぇよってツッコミはなし。

文字列型と数値型の値の参照渡し

  first  = 1
  second = first

  p first
  p second

のときの動作としてはこんな感じ

スクリーンショット 2020-09-18 23.15.36.png

これをそのまま出力するとこうなる。

 1
 1

これを代入し直すと

  second = 2

  p first
  p second

スクリーンショット 2020-09-18 23.25.38.png

こんな動きになる。
出力はもちろん

  1
  2

ここまでは値渡しと同じ見た目のため、混同されやすい。
とりあえずは、
参照しているメモリの値がメモリ番号から他のオブジェクト(今回は数値型)に切り替わることで、値渡しと同じような動作になる
文字列も原理は同じため省略。

リストとハッシュの参照の値渡し

rubyの配列の話。
個人的にはリストの方がしっくりくるので以後配列リストと呼称する。

  first_list = [1,2]
  second_list= first_list

  p first_list
  p second_list

このときの出力はもちろんこうなる。

  [1,2]
  [1,2] 

さぁ代入してみよう

  second_list[0]=3

  p first_list
  p second_list

このとき、参照の値渡しを知らないとこのような出力を期待する。

  [1,2]
  [3,2]

無慈悲にも実際にはこう

  [3,2]
  [3,2]

え、なんで?

このときの内部の動きを見てみる。
ここから少しややこしいので注意。

最初のコピーの時

スクリーンショット 2020-09-19 0.04.17.png

 代入時

スクリーンショット 2020-09-19 0.06.27.png

こうなる。
rubyの特性上リストもオブジェクトのため、
その配下の別のオブジェクト(今回は数値型のオブジェクト)の値が入れ替わる。
つまり、
リスト・ハッシュの代入の際は、リスト・ハッシュに代入するのではなく、配下のオブジェクトに代入している

この事象を回避したい!

回避するためには、実際に見られる値自体を複製する必要がある。
一番手軽な方法はこちら

first_list=[1,2]
second_list=first_list.map{ |num| num }

p first_list
p second_list

second_list[0] = 3

p first_list
p second_list

出力はこう

  [1,2]
  [1,2]
  [1,2]
  [3,2]
なぜ?

スクリーンショット 2020-09-19 0.51.52.png

中でこのように新しいリストを作成しつつ、
mapメソッドを使用してリスト配下のオブジェクト自体ををコピーしている。(最初の数値型と同じコピー)
その後に行う代入も最初のコピーと同じ動作が起こる。

まとめ

  1. rubyではコピーされる際に、対象のオブジェクトの位置をコピーする。
  2. 参照の値渡しは、メモリ番号らしきものをコピーする。
  3. 参照の値渡しも図にしちゃえば怖くない。

rubyの学習を進めていくと object_idやら何やら出てきますが、メモリ位置のようなものとして受け取っておけば理解しやすいです。
ざっくり説明するために細かい言葉などは正確ではありませんが、この記事が誰かの役に立てば嬉しいです。

それでは、良いrubyライフを。

0
0
0

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?