2012-04-19 13 views
1

私は何か非常に根本的な欠点があるように感じます。なぜなら、より多くの髪を引き裂かないようにするために、p1、p1t、p1t2が "hand = newgame" p1を見る。私はなぜp1が変更されているのか分からないので、私はここで完全に困惑しています。どんな助けでも大いに感謝します。変数の基本的な問題

# encoding: utf-8 

class Cards 

def view hand 
    x = 0 
    hand.each do |card| 
     if card[0] == 's' 
      card[0] = '♠' 
     elsif card[0] == 'd' 
      card[0] = '♦' 
     elsif card[0] == 'h' 
      card[0] = '♥' 
     elsif card[0] == 'c' 
      card[0] = '♣' 
     else 
      #nil 
     end 
     hand[x] = card 
     x = x + 1 
    end 
    prettyhand = '' 
    hand.each do |card| 
     prettyhand = prettyhand + card[0] + card[1] + ' ' 
    end 
    return prettyhand 
end#view 

end#Cards 
########### 

deck = 0 
up = 0 
p1 = 0 
p2 = 0 
newgame = Cards.new 
p1 = [["c", "4"], ["s", "4"], ["d", "q"], ["c", "8"], ["s", "5"], ["s", "q"], ["h", "3"], ["c", "10"]] 
    p1t = [] 
    p1t2 = [] 
    hand = '' 
    p1.each do |card| 
     p1t.push card 
    end 
    p1t.each do |card| 
     p1t2.push card 
    end 
    p '----------------------------------' 
    p 'fresh p1:' 
    p p1 
    p p1t 
    p p1t2 
    hand = newgame.view p1 
    p 'unfresh p1:'#why is this changing?? 
    p p1 
    p p1t 
    p p1t2 
    p '----------------------------------' 

出力:あなたは括弧もメソッドシグネチャでは、あなたは常にあなたのコードでそれらを省略する理由はわからないいいです、hand(BTWパラメータを取る方法viewを定義している

"----------------------------------" 
"fresh p1:" 
[["c", "4"], ["s", "4"], ["d", "q"], ["c", "8"], ["s", "5"], ["s", "q"], ["h", "3"], ["c", "10"]] 
[["c", "4"], ["s", "4"], ["d", "q"], ["c", "8"], ["s", "5"], ["s", "q"], ["h", "3"], ["c", "10"]] 
[["c", "4"], ["s", "4"], ["d", "q"], ["c", "8"], ["s", "5"], ["s", "q"], ["h", "3"], ["c", "10"]] 
"unfresh p1:" 
[["♣", "4"], ["♠", "4"], ["♦", "q"], ["♣", "8"], ["♠", "5"], ["♠", "q"], ["♥", "3"], ["♣", "10"]] 
[["♣", "4"], ["♠", "4"], ["♦", "q"], ["♣", "8"], ["♠", "5"], ["♠", "q"], ["♥", "3"], ["♣", "10"]] 
[["♣", "4"], ["♠", "4"], ["♦", "q"], ["♣", "8"], ["♠", "5"], ["♠", "q"], ["♥", "3"], ["♣", "10"]] 
"----------------------------------" 

答えて

1

配列はコピーされずに参照渡しされます。このスニペットをご覧ください。

a1 = [[1], [2], [3]] 
a2 = [] 

a2 << a1.first # push a reference to the array 
a2 # => [[1]] 


a1[0][0] += 1 # => 2 
a1 # => [[2], [2], [3]] # a1 has changed 
a2 # => [[2]] # a2 changed too! 

# now push a copy of the array 
a2 = [a1.first.dup] # => [[2]] 

a1[0][0] += 1 # => 3 
a1 # => [[3], [2], [3]] # a1 has changed 
a2 # => [[2]] # a2 has not 
+2

特に、これはメソッド呼び出しにも当てはまります。したがって、あなたのCards#viewメソッドは引数を変更します。 –

+0

私は理解すると思います!それでは、ここで最高の解決策は何ですか?配列を文字列に変換してコピーを作成する必要がありますか?ありがとう! – catbat

+0

@catbat:私の更新された答えをチェックしてください –

1

)。 viewメソッドは、その引数handを変更します。あなたはこの

hand = newgame.view p1 

としてそれを呼び出す、 p1は法 viewによって変更され、それが変わる理由です。

p10に設定して、それを配列の配列に設定するのも、私は興味があります。それをする理由はありません。また、あなた自身と他の人のために、記述的な変数名を使用しようとしてください。

+0

Merci - 「署名」と言うとき、これは返品行を意味しますか? – catbat

+0

@catbat:申し訳ありません。これは、メソッドの名前と、それが取る引数(静的言語では戻り値の型)を意味します。だから、 'def view(手)'がメソッドシグネチャです。 –

+0

入手しました。私は通常それらを使用し、今後も引き続き使用し続けます。編集:それはちょうど急いで一緒にスローされているので、それは奇妙に見えます。それを0に設定したのは、何らかの目的のために行われていませんでした。> – catbat

1

FWIWは、あなたのview方法は、多くのことを簡単にすることができます。

class Cards 
    Suits = { 'c' => '♣', 'd' => '♦', 'h' => '♥', 's' => '♠' } 

def view(hand) 
    hand.map do |suit, rank| [ Suits[suit], rank ] end 
end 
end 

このバージョンでは何も変更されませんので、問題を回避できます。

+0

これは非常に面白いです。私はそれに精通していないので、私はマップ上でいくつかの読書を行う必要がありますが、それははるかに簡単なアプローチと思われる。グラシアス! – catbat

+0

map( 'collect'とも呼ばれます)は、いくつかの変更を加えて配列のコピーを作る良い方法です。すべての要素で実行されるコードブロックを指定します。ブロックの戻り値がコピー内の置換要素になります。たとえば、リスト内のすべての数字をインクリメントするには、次のようにします。 '[1,2,3] .map {| x | x + 1} 'は' [2,3,4] 'を返します。 –

+0

非常に便利です。再度、感謝します! – catbat