0

配列から要素をポップしようとすると、ポップします。ポップする前にその配列を別の変数に割り当てると、ポップすると、ポップ操作が両方の配列に影響します。

例えば:

 ruby-1.9.2-p290 :339 > a= [1,2,3]
     => [1, 2, 3] 
    ruby-1.9.2-p290 :340 > b = a
     => [1, 2, 3] 
    ruby-1.9.2-p290 :341 > a
     => [1, 2, 3] 
    ruby-1.9.2-p290 :342 > b
     => [1, 2, 3] 
    ruby-1.9.2-p290 :343 > a.pop
     => 3 
    ruby-1.9.2-p290 :344 > a
     => [1, 2] 
    ruby-1.9.2-p290 :345 > b
     => [1, 2] #WHY?
    ruby-1.9.2-p290 :346 > x = [1,2,3]
     => [1, 2, 3] 
    ruby-1.9.2-p290 :347 > y = x
     => [1, 2, 3] 
    ruby-1.9.2-p290 :348 > z = x
     => [1, 2, 3] 
    ruby-1.9.2-p290 :349 > y
     => [1, 2, 3] 
    ruby-1.9.2-p290 :350 > z
     => [1, 2, 3] 
    ruby-1.9.2-p290 :351 > y.pop
     => 3 
    ruby-1.9.2-p290 :352 > y
     => [1, 2] 
    ruby-1.9.2-p290 :353 > z
     => [1, 2] # WHY?
    ruby-1.9.2-p290 :354 > x
     => [1, 2] 
    ruby-1.9.2-p290 :355 > 

popを使用すると、すべての変数が影響を受けます。元の配列を保持し、他の配列からのみポップするにはどうすればよいですか?

4

3 に答える 3

6

配列を新しい変数に割り当てる場合、その配列はコピーされませんが、元の配列への参照を設定するだけです。元の配列を保持したい場合は、次を使用して複製する必要がありますdup

ruby-1.9.2-p180 :001 > a = [1,2,3]
 => [1, 2, 3] 
ruby-1.9.2-p180 :002 > b = a.dup
 => [1, 2, 3] 
ruby-1.9.2-p180 :003 > b.pop
 => 3 
ruby-1.9.2-p180 :004 > a
 => [1, 2, 3] 
ruby-1.9.2-p180 :005 > b
 => [1, 2] 
于 2012-05-01T12:05:32.777 に答える
3

rubyの代入演算子は、数値や文字列などのPOD(Plain Old Data)オブジェクトを処理する場合にのみ、値のコピーを作成します。それ以外の場合は、オブジェクトへの参照をコピーするだけです。

dupそして、その(およびclone)メソッドはオブジェクトの浅いコピーのみを作成することを忘れないでください。これは、配列に他の非PODオブジェクトが含まれている場合、それらはコピーされないことを意味します。

inner = [1,2,3]
 => [1, 2, 3]
outer = [inner, 7,8,9]
 => [[1, 2, 3], 7, 8, 9]

outer_dup = outer.dup
inner.pop
 => 3

outer
 => [[1, 2], 7, 8, 9]
outer_dup
 => [[1, 2], 7, 8, 9]

メソッドをオーバーライドcloneして自分でディープコピーを作成することで、これを回避できます。

于 2012-05-01T12:28:49.500 に答える
0

Rubyは非常にオブジェクト指向です。ごくわずかな例外を除いて、Rubyはほとんどの場合、値ではなく参照によって変数を渡します。これは非常に重要な概念です。これをチェックしてください。ルビーではありませんが、少しわかりやすくするのに役立つかもしれません。お役に立てば幸いです。

于 2012-05-01T12:15:39.067 に答える