1
class Foo
  def bar
    @instance_variable = [['first']]

    # make a duplicate object with the :dup method
    local_variable=@instance_variable.dup

    # They have different object_id
    p @instance_variable.object_id
    p local_variable.object_id


    local_variable.each{|n|n.push('second')}
    @instance_variable
  end
end

f=Foo.new
p f.bar

=> 2000
=> 2002
=> [["first", "second"]]

別のオブジェクトですが、local_variableはまだ@instance_variableを参照しているようです。この動作は、と各ブロックの両方でpush発生unshiftします。のような通常の割り当てlocal_variable='second'では、結果は期待どおりです=> [['first']]

local_variable.each{|n|n.push('second')}なぜ影響があるのか​​わかりません@instance_variable

Rubyの使用-1.9.2p318

4

2 に答える 2

2

両方ともlocal_variable@instance_variable同じオブジェクトである内部配列への参照があります['first']。また、これは可変アレイであるため、一方のアレイにもう一方のアレイを介して変更を加えることができます。

Object#dupRubyでは浅いコピーを提供します。配列のディープコピーを作成するには、データ構造を再帰的にウォークし、可変状態の断片をディープクローンするコードを作成する(またはライブラリを見つける)必要があります。

于 2013-02-10T23:26:14.713 に答える
1

問題は、適切なオブジェクトをテストしていないことです。あなたは言う:

p @instance_variable.object_id
p local_variable.object_id

しかし、それはあなたがプッシュしようとしているオブジェクトではありません。代わりにこれを試してください:

p @instance_variable[0].object_id
p local_variable[0].object_id

それら同じオブジェクトです。

つまり、変更を変更することはできませんが、両方に同じオブジェクトへの参照が含まれているため、一方が指すようにそのオブジェクトを変更すると、もう一方が指すようにそのオブジェクトが変更されます。local_variable@instance_variable

于 2013-02-10T23:30:06.960 に答える