1

テスト用に2つのrubyファイルを作成しました

test.rb:

#!/usr/bin/ruby

def foo(bar)
    bar['key'] = 'value'
end

def my_print(a)
    a.each{|k,v|
        puts "#{k} => #{v}"
    }
end

test_drive.rb:

#!/usr/bin/ruby

require 'test.rb'

hash_test = Hash.new

foo(hash_test)

my_print(hash_test)

それは私が期待するように機能し、出力は

キー=>値

しかし、test.rbを変更すると

#!/usr/bin/ruby

def foo(bar)
    pre_defined = {'key' => 'value'}
    bar = pre_defined
end

def my_print(a)
    a.each{|k,v|
        puts "#{k} => #{v}"
    }
end

ここでは事前定義されたハッシュを使用しましたが、現在は何も出力しません。「hash_test」は空のハッシュになりました。なぜこれが実際に起こるのか説明してください。

4

2 に答える 2

3

簡単な答えは次のとおりです。

ルビーでは、参照によってオブジェクトを使用して変数を渡します。オブジェクトを変数に割り当てる場合、変数には実際にはオブジェクト自体が含まれていません。代わりに、そのオブジェクトへの参照のみが含まれます。

パラメータとして変数を送信する方法を理解するために、参照とオブジェクトの違いを確認し始めると役立つ場合があります。オブジェクト自体は変数に存在せず、変数はメモリ内のオブジェクトの参照を指しているためです。これは、ある変数が別のオブジェクトを指し、それを変更した場合、それが以前に参照していたオブジェクトを変更したことを意味するわけではありません。

理解しておくべき重要なことは、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がそれを印刷しようとすると空になります。

于 2012-05-24T07:30:27.813 に答える
1

つまり、Rubyは値渡しであるため、オブジェクトの参照が渡されます。これは、Javaが行うのと同様の動作です。つまり、fooメソッド内には参照のコピーしかなく、それを再割り当てしても、このメソッドの外部の参照は変更されません。

詳細:最初の例では、ハッシュをfooメソッドに渡します。参照がコピーされるため、foo-method内に、「hash_test」と同じオブジェクトを指す参照のコピーがありますが、同じオブジェクトではありません。したがって、Hashメソッドを呼び出すと、メソッド外のオブジェクトの値が変更されます。ただし、2番目の例では、指定されたハッシュの値を変更しない場合、メソッド参照のコピーに新しいハッシュオブジェクトを割り当てます。これは、「hash_test」参照には影響しません。

于 2012-05-24T06:45:08.250 に答える