2012-05-01 18 views
0

配列から要素をポップしようとすると、ポップします。ポップする前にその配列を別の変数に代入すると、ポップするとpopの操作が両方の配列に影響します。例えば他の変数に影響を与えずにルビーポップ配列

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 > 

私はポップを使用している場合は、すべての変数が影響を受けます。私は元の配列を保持し、もう一方をポップしたい。どうやって?

+0

あなたの編集は異なる質問です。新しい質問を開いてください。 – Mischa

+0

@ミシャ:質問しました。ご協力ありがとうございました! – beck03076

答えて

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] 
+0

伝説的な............. !!! – beck03076

0

Rubyは非常にオブジェクト指向です。ごくわずかな例外を除いて、Rubyはほとんどの場合、値ではなく参照によって変数を渡します。それはかなり重要な概念です。 Check this out。それはルビーではありませんが、それは少しそれをdemystifyに役立つかもしれません。希望が助けてくれる!

+0

-1。これは間違っている。まず、Rubyは値渡しです。第二に、例外はありません。Rubyは*常に*値渡しです。 Ruby(または他の言語)が参照渡しであるか値渡しであるかを知りたければ、それを試してみてください: 'def foo(bar)bar = 'reference' end; baz = '値'; foo(baz); "Rubyはパスバイ#{baz}"となります。 –

+1

この件について投稿した他の投稿を読んだら、厳密なコンピュータサイエンスの言葉を守っていることは明らかです。この場合、ちょうどフラットアウトは意味をなさない。 OPは、オブジェクトを周回することについて質問しています。ペダンシーではないと考えてください。 –

+0

私は、プリミティブを持っていなくても、オブジェクトだけを持っているRubyについて話しています。あなたが私を信じていない場合、あなた自身がIRbにカット&ペーストすることができる私のコメントに私は簡単なテストプログラムを提供しました。 –

3

ルビの代入演算子は、数値、文字列などの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メソッドをオーバーライドすることでそれを避けることができます。

+0

ご協力ありがとうございます。 "dup"は私が探していたものです。なぜ私がそれを望んでいたのか理解するために質問の編集セクションを見てください、ありがとう! – beck03076

+0

@Flexoid、私の答えを拡大してくれてありがとう。 +1 – Mischa