0

重複の可能性:
Ruby は参照渡しですか、それとも値渡しですか?

Ruby でオブジェクトをメソッドに渡すとき、このオブジェクトのメモリはどのように処理されますか?

C のバックグラウンドから来て、起こっている可能性のあるいくつかのことを考えることができます。

  1. 該当するオブジェクトに関連付けられたメモリのコピーであり、呼び出されるメソッドで使用できるようになります。その場合、オブジェクトの変更は、呼び出し元のメソッドではなく、呼び出されるメソッドのコンテキストにのみ反映されます。

  2. オブジェクトのメモリへの参照は、呼び出されるメソッド (基本的にはポインター) に渡されます。したがって、呼び出されるメソッドまたは呼び出し元のメソッドによってオブジェクトによって行われた変更は、両方のコンテキストに反映されます。同様に、このプログラムがマルチスレッド化されている場合、何らかのメカニズム (mutex、セマフォなど) を使用して、書き込み操作を実行するメモリへの相互排他的アクセスを保証する必要があります。

  3. 私が考えることができない他の何か...おそらくGoのそれに似たメモリモデル...パイプ...メッセージパッシング...?

実際に何が起こっているのですか?

4

2 に答える 2

2

Ruby は値渡しを使用します。より正確には、渡される値が常にポインターである値渡しの特殊なケースです。この特殊なケースは、call-by-sharing、call-by-object-sharing、call-by-object とも呼ばれます。

これは、多かれ少なかれ、これまでに作成されたすべてのオブジェクト指向言語で使用されているのと同じ規則です。

注: すべての既存の Ruby 実装では、s SymbolFixnums、およびFloats は実際には値によって直接渡され、中間ポインターでは渡されません。ただし、これら 3 つは不変であるため、この場合、値渡しとオブジェクト呼び出しによる共有の間に目に見える動作の違いはありません。そのため、すべてをオブジェクト呼び出しとして扱うだけで、メンタル モデルを大幅に簡素化できます。 -共有。これら 3 つの特殊なケースは、心配する必要のない内部コンパイラの最適化として解釈してください。

以下は、Ruby (または翻訳後の他の言語) の引数受け渡し規則を判別するために実行できる簡単な例です。

def is_ruby_pass_by_value?(foo)
  foo.replace('More precisely, it is call-by-object-sharing!')
  foo = 'No, Ruby is pass-by-reference.'
  return nil
end

bar = 'Yes, of course, Ruby *is* pass-by-value!'

is_ruby_pass_by_value?(bar)

p bar
# 'More precisely, it is call-by-object-sharing!'

要するに、それはあなたのオプションです 2.

于 2012-09-07T23:38:41.703 に答える
2

Ruby は 2 番目のオプションを使用し、パラメーターを参照渡しします。

于 2012-09-07T18:19:22.387 に答える