ruby

メソッドの引数(値渡し、参照渡し)

Rubyの引数は値渡しです。

Rubyの引数は値渡しです。参照渡しではありません。ググるとそのようにまとめてらっしゃる方が多々ありますので間違いはないとおもいます。Ruby リファレンスマニュアルで探してみたんですが、記載を見つけられませんでした、確認でき次第アドレスを掲載します。
(*1)参考リンクを追加しました。

ここではRubyの引数(値渡し,参照渡し)について自分なりにまとめてみます。

Rubyist Magazine – 値渡しと参照渡しの違いを理解する

を深く読んでください。を深く読んでください。を深く読んでください。
この記事よりもよっぽど詳しいです。。。

メソッドの復習と名称

def hoge(a) # メソッド: hoge, 仮引数: a
    a += 10 # a に 10 を足す
end

x = 10 # 変数 x
hoge(x) # メソッド hoge に、実引数 x を渡す

値渡しと参照渡し

値渡しと参照渡しについて簡単に説明します。詳細は本当にググってください…

・値渡し (call by value) :実引数として変数を渡しても、その値のみが渡される。そのため、仮引数を変更しても、実変数は変更されない。

def hoge(a) # メソッド: hoge, 仮引数: a
    a += 10 # a に 10 を足す
    p a # => 20
end

x = 10 # 変数 x
hoge(x) # メソッド hoge に、実引数 x を渡す
p x # => 10

・参照渡し (call by variable) :実引数として変数を渡しすとき、変数に対する参照(メモリ番地)先を渡す。そのため、仮引数の値を変更すると、実変数の値も同様に変更されたことになる。

def hoge(a) # メソッド: hoge, 仮引数: a
    a += 10 # a に 10 を足す
end

x = 10 # 変数 x
hoge(x) # メソッド hoge に、実引数 x を渡す
p x # => 20

注)仮のコードです、rubyでは動作確認できません

引数(実引数)が配列の場合

Rubyは『値渡し』です。しかし、実引数にが配列の場合『参照渡し』のような結果になるときがあります。実引数で渡した配列が、仮引数の値を変更すると実引数の値も変わってしまう『副作用』が生じます。実はこの時『参照の値渡し』と言う値渡しが行われています。
理屈は以前の記事オブジェクトのコピーと同じで、実引数も仮引数も同じオブジェクトを見ている、仮引数にはオブジェクトの参照の値が渡されたということになります。

def hoge(a) # メソッド: hoge, 仮引数: 配列 a
    a[0] += 10 # 配列a[0] に 10 を足す
end

x = [10] # 変数: 配列 x
hoge(x) # メソッド hoge に、実引数 x を渡す
p x # => [20] # 実引数の値が変更されている

objcet_idを確認してみる

def hoge(a)
    a[0] += 10
    p a.object_id # => 17968120
end

x = [10]
p x.object_id # => 17968120
hoge(x)
p x # => [20] # 実引数の値が変更されている

*)object_idで同一性を確認しているだけです。rubyではメモリの番地を調べることはできないようです。

引数(実引数)が配列の場合の『副作用』を予防する

この副作用を予防するには、実引数と仮引数が別のオブジェクトを参照していれば良いということになります。なので、複製を作ればOKになります。

def hoge(a)
  p a.object_id # => 540724920
end

x = [1, 2, 3, 4, 5]
p x.object_id # => 539436540
temp = x.clone
hoge(temp)
def hoge(*a) # * 複数の引数を配列として受け取ります。
  p a.object_id # => 539428060
end

x = [1, 2, 3, 4, 5]
p x.object_id # => 539443780
hoge(*x) # * 展開して渡します

sample01, sample02 もobject_idが違うので、『副作用』は起こりません。

しかし・・・多重配列だと・・・別の機会追記しました。

Rubyist Magazine – 値渡しと参照渡しの違いを理解する

引数 – Wikipedia

*1)お気楽 Ruby プログラミング入門第 3 回●値呼びと参照呼び

変数や定数は,あるオブジェクトを指しています.何も代入しなくても nilオブジェクトを指しています.代入は,変数や定数が新しいオブジェクトを 指すようにします.

したがって,代入によりオブジェクトがコピーされて新しく作られることは なく,右辺の表現の表しているオブジェクトを左辺の変数や定数が指すように することが代入によって行われます.

*1)Ruby FAQ: 変数,定数,引数(文字化けします、EUCで開いてください)