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のオブジェクトがメモリ上でどう表現されるのか」とか全然わかってないから大事なことをごまかしたまま、イメージ図でふんわり理解したフリをしているだけだな。以下の記事などを理解できたらよさそう。