いまいちちゃんと理解していなかったので改めてまとめる
大前提としての値渡し、参照渡し
プログラミング言語の引数の渡り方の話で出てくるフレーズなので説明としては簡素に記述するが
- 値渡しは呼び出し元の実数値(実引数の値)を呼び出した関数の引数(仮引数)に渡す方式
- 参照渡しは呼び出し元の引数の保存されている領域の情報元の実数値(実引数の参照情報)を呼び出した関数の引数(仮引数)に渡す方法
Rubyでは参照の値渡し(≒共有渡し)
るびまに以下のような記事がある。
こちらより引用すると
・Ruby (や多くのプログラミング言語) は値渡しである。
・変数が参照 (= メモリ番地) を保持している場合は、それが引数にコピーされる。
・そのため、変数 (実引数) と引数 (仮引数) とが同じオブジェクトを共有することになるので、引数が指すオブジェクトを変更すると、もとの変数のオブジェクトも変更される。
・「変数を変更する」ことと「変数が指すオブジェクトを変更する」ことは別である。
というように値渡しが基本ではあるが、変数に入っている実態数値がセットされているわけではなく、「参照の情報が値渡しされている」という表現になっている
具体的にはどういうことか
純粋な値渡しの例
例えば下記のような処理を書く
def irekae(a,b) temp_a = a temp_b = b a = temp_b b = temp_a end
下記を実行してもaとbの値は入れ替われない。
a = 200 b = 100 irekae(a,b) pp a pp b
上記の実行結果は以下となる
200 100
参照の値渡しの例
参照をしている情報を渡しているだけなので、参照先のオブジェクトの中身を変更すると値が変更となる。配列の例は参考サイトにもあるのでオブジェクトの例を下記に示す。
まずは利用するクラスを定義する
class Monoire def initialize(value) @atai = value end def set_atai(value) @atai = value end def get_atai return @atai end end
そして下記のように利用する
def change_monoire(target) target.set_atai(200) end temp = Monoire.new(100) pp "before atai = #{temp.get_atai}" change_monoire(temp) pp "after atai = #{temp.get_atai}"
そうすると下記のような出力結果となりtempはメソッドでの処理の影響を受ける。
"before atai = 100" "after atai = 200"
参考サイト
参照の値渡しと共有渡しに関しては呼び方にいろいろあるので参考サイトを読んで頂くとよさそう。