2019-07-05
Rubyにおける(オブジェクトへの参照の)値渡しを理解しようとして無知を感じた
Ruby のメソッド呼び出しではだいたい全部(オブジェクトへの参照を)値渡しする。
ミュータブルなオブジェクトの場合
def method(param)
p param # => "hoge"
p param.object_id # => 47397028882260
param.upcase!
p param # => "HOGE"
p param.object_id # => 47397028882260
end
arg = "hoge"
p arg # => "hoge"
p arg.object_id # => 47397028882260
method(arg)
p arg # => "HOGE"
p arg.object_id # => 47397028882260
メモリの状態を追っていく。
まずarg = "hoge"
の直後。
メモリ番地 | 変数名 | オブジェクト番号 | 中身 |
---|---|---|---|
0x0000 | arg | obj47397028882260(への参照) | |
0x1000 | obj47397028882260 | (“hoge”という文字列オブジェクト) |
method(arg)
でメソッド内に入った直後。param をつくり、オブジェクトへの参照を値渡ししている点に注意。
メモリ番地 | 変数名 | オブジェクト番号 | 中身 |
---|---|---|---|
0x0000 | arg | obj47397028882260(への参照) | |
0x0001 | param | obj47397028882260(への参照) | |
0x1000 | obj47397028882260 | (“hoge”という文字列オブジェクト) |
param.upcase!
の直後。文字列オブジェクトはミュータブルなので、既存のオブジェクトが書き換えられる。
メモリ番地 | 変数名 | オブジェクト番号 | 中身 |
---|---|---|---|
0x0000 | arg | obj47397028882260(への参照) | |
0x0001 | param | obj47397028882260(への参照) | |
0x1000 | obj47397028882260 | (“HOGE”という文字列オブジェクト) |
なので、メソッドからでた後にarg
は”HOGE”を返す。
イミュータブルなオブジェクトの場合
def method(param)
p param # => 555
p param.object_id # => 1111
param = param + 10
p param # => 565
p param.object_id # => 1131
end
arg = 555
p arg # => 555
arg.object_id # => 1111
method(arg)
p arg # => 555
p arg.object_id # => 1111
arg = 555
の直後。
メモリ番地 | 変数名 | オブジェクト番号 | 中身 |
---|---|---|---|
0x0000 | arg | obj1111(への参照) | |
0x1000 | obj1111 | (555 という数値オブジェクト) |
method(arg)
でメソッド内に入った直後。param をつくり、オブジェクトへの参照を値渡ししている点に注意。
メモリ番地 | 変数名 | オブジェクト番号 | 中身 |
---|---|---|---|
0x0000 | arg | obj1111(への参照) | |
0x0001 | param | obj1111(への参照) | |
0x1000 | obj1111 | (555 という数値オブジェクト) |
param = param + 10
の直後。数値オブジェクトはイミュータブルなので、既存の数値オブジェクトはそのままに、新しい数値オブジェクトがつくられる。
メモリ番地 | 変数名 | オブジェクト番号 | 中身 |
---|---|---|---|
0x0000 | arg | obj1111(への参照) | |
0x0001 | param | obj1131(への参照) | |
0x1000 | obj1111 | (555 という数値オブジェクト) | |
0x1001 | obj1131 | (565 という数値オブジェクト) |
なので、メソッドからでた後にarg
は 555 を返す。
おわりに
なんかまとめたけど、やっぱ「Ruby のオブジェクトがメモリ上でどう表現されるのか」とか全然わかってないから大事なことをごまかしたまま、イメージ図でふんわり理解したフリをしているだけだな。以下の記事などを理解できたらよさそう。