0

オブジェクトをモジュール メソッドに渡すとどうなるかわかりません。オブジェクトは参照またはコピーによって渡されますか? この例のように:

module SampleModule
  def self.testing(o)
    o.test
  end
end

class SampleClass
  def initialize(a)
    @a = a
  end

  def test
    @a = @a + 1
  end
end

sample_object = SampleClass.new(2)
3.times do
  SampleModule.testing(sample_object)
end
p sample_object # => #<SampleClass:somehexvalue @a=5>

通りすがりの参照のようです。これについては本当に不明です。

4

3 に答える 3

2

Rubyのすべての変数はオブジェクトへの参照です。C、C++、または Perl で選択できるのと同じ方法で、「値渡し」と「参照渡し」を行うことはできません。実際、Ruby は値渡しを強制します。それ以外の方法はありません。ただし、送信される値は常にオブジェクトへの参照です。これは、すべてのメンバー変数がポインターである C または C++ を使用する場合や、単純なスカラーを使用する場合でも常に参照を使用する必要がある Perl を使用する場合に少し似ています。

あなたを混乱させているのは、この変数とオブジェクトデータの分離だと思います。

いくつかのポイント:

  • 変数の割り当てでは、同じオブジェクトを指す可能性がある他の変数が上書きされることはありません。これはほとんど値渡しの定義です。ただし、これは、オブジェクトのコンテンツも保護されるという期待に応えていません。

  • インスタンス変数、およびコンテナー内の項目 ( Arrays およびStrings など) は別個の変数であり、コンテナーを送信する場合、コンテナーへの参照を送信したため、コンテナーの内容を直接変更することができ、その内容には同じ変数が含まれます。これが「参照渡しのようだ」という意味だと思います

  • 一部のクラス (数値を表すクラスや、数値を表すクラスなどSymbol) は不変です。つまり、数値のインプレース変更メソッドはありません4。しかし、概念的には、まだ特異なオブジェクトへの参照をルーチンに渡しています4(内部では、効率のために、Ruby は4変数のメモリ割り当てで単純にエンコードされた値を持ちますが、それは実装の詳細です。値は「ポインタ」でもあります)。この場合)。

  • あなたが探していると思われる「値渡し」のセマンティクスに近づく最も簡単な方法は、ルーチンの開始時にパラメーターを使用することです。これは、Ruby が呼び出しのセマンティクスを実際に変更する原因にはならないことに注意してください。この場合、メソッドの外側から、安全な仮定 (メソッド内の param に何が起こっても、メソッド内にとどまる) が得られます。SampleModuleclone


module SampleModule
  def self.testing(o)
    o = o.clone
    o.test
  end
end
  • 技術的には、これはジェネリックである深いクローンである必要がありますが、例を値渡しに近づけるためには必要ありません。呼び出して、コードの残りの部分がSampleModule.testing( any_var_or_expression )何であれ、関連付けられているオブジェクトが変更されていないことを知ることができます。any_var_or_expression
于 2013-11-09T12:16:19.800 に答える