参照についてのメモ

ちょっと前書き留めた、オブジェクト参照の値渡しについてのメモが出てきた。確か事の発端は「リファクタリングRubyエディション」p151-p153の
下記の文。

Rubyでは、値渡しを使っていることが何かと混乱の原因となる。Rubyは、すべての箇所で厳密に値渡しを使っている…(途中略)…オブジェクト参照は値渡しされる。オブジェクト参照を使ってメソッドを呼び出したり、状態に変化を加えたりすることは可能で、呼び出しスタックの上でも変更結果は有効である。しかし、オブジェクト参照に代入をしても、このオブジェクト参照は値渡しされているため、メソッド本体のスコープを離れると、この代入の効果は反映されなくなってしまう。

で、試してみた。

def hoge(arg)
  arg[:key2] = 2
  print_hash(arg, 'hash in hoge.')
end

def hoge2(arg)
  arg = Hash.new
  arg[:key100000] = 100000
  print_hash(arg, 'hash in hoge2')
end

def print_hash(hash, comment)
  puts comment
  p hash
end

hash = Hash.new
hash[:key1] = 1

#hoge
print_hash(hash, 'hash before hoge.')
hoge(hash)
print_hash(hash, 'hash after hoge.')

puts '---'

#hoge2
print_hash(hash, 'hash before hoge2.')
hoge2(hash)
print_hash(hash, 'hash after hoge2.'

結果は、

hash before hoge.
{:key1=>1}
hash in hoge.
{:key1=>1, :key2=>2}
hash after hoge.
{:key1=>1, :key2=>2}
    • -
hash before hoge2. {:key1=>1, :key2=>2} hash in hoge2 {:key100000=>100000} hash after hoge2. {:key1=>1, :key2=>2}

メソッド引数で渡されているのはHashオブジェクトの参照値のコピーなのでそこに新しいHashオブジェクトを代入してもメソッド抜けると効果が無くなっているという話。でいいんだよね??