簡単な答えは次のとおりです。
ルビーでは、参照によってオブジェクトを使用して変数を渡します。オブジェクトを変数に割り当てる場合、変数には実際にはオブジェクト自体が含まれていません。代わりに、そのオブジェクトへの参照のみが含まれます。
パラメータとして変数を送信する方法を理解するために、参照とオブジェクトの違いを確認し始めると役立つ場合があります。オブジェクト自体は変数に存在せず、変数はメモリ内のオブジェクトの参照を指しているためです。これは、ある変数が別のオブジェクトを指し、それを変更した場合、それが以前に参照していたオブジェクトを変更したことを意味するわけではありません。
理解しておくべき重要なことは、fooメソッドのbarパラメーターは、実際には、オブジェクト自体ではなく、メモリー内のオブジェクトへの参照にすぎないということです。したがって、バーがかつてオブジェクトを指していたが、現在は別のオブジェクトを参照している場合、それは、前に指していたオブジェクトではなく、参照しているものを変更します。これが最後のtest.rbのコードで、理解しやすいように少しコメントが付けられています。
def foo(bar) # here "bar" points to the same object as "hash_test"
pre_defined = {'key' => 'value'} # here a new object is created and referenced
bar = pre_defined # now "bar" points to a new object and forgets about "hash_test"
end
def my_print(a) # here "a" holds a reference to "hash_test" which is empty
a.each{|k,v| # "a" is empty, so it has nothing to put
puts "#{k} => #{v}"
}
end
これがお役に立てば幸いです。もう少し詳細なものが必要な場合:
test.rbの最後のバージョンがtest_drive.rbに空のハッシュを出力する理由は、参照「hash_test」が指すハッシュオブジェクトが実際にはまったく変更されていないためです。代わりに、fooメソッドは、最初に「bar」と呼ばれるパラメーターとして「hash_test」が指すハッシュオブジェクトの参照を受け取りますが、「bar」内のその参照を、「 pre_defined"変数はを指します。これで、「bar」は「hash_test」と同じオブジェクトを指さないため、「hash_test」が指すオブジェクトは変更されません。したがって、「hash_test」に含まれるハッシュオブジェクトには実際には何も入力されず、my_printがそれを印刷しようとすると空になります。