2012-04-19 80 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 '----------------------------------' 

輸出:

"----------------------------------" 
"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方法修改了它的參數。 – 2012-04-19 01:38:09

+0

我想我明白了!那麼,這裏最好的解決方案是什麼?我應該將數組轉換爲字符串來複制它們嗎?謝謝! – catbat 2012-04-19 01:42:22

+0

@catbat:查看我的更新回答 – 2012-04-19 01:46:41

1

您已經定義了一個方法view這需要一個參數hand(順便說一句,括號都不錯,不知道爲什麼你總是忽略它們在你的代碼,即使是在方法簽名)。 view方法修改其參數hand。你把它作爲

hand = newgame.view p1 

p1由法view修改,這就是爲什麼它的變化。

我也很好奇你爲什麼設置p10 ...然後將其設置爲一個數組數組。沒有理由這樣做。此外,嘗試使用描述性變量名稱,以及其他人。

+0

謝謝 - 當你說'簽名'時,這是否意味着返回線? – catbat 2012-04-19 01:41:14

+0

@catbat:對不起。它表示方法的名稱和參數(以靜態語言表示返回類型)。所以'def view(hand)'是方法簽名。 – 2012-04-19 01:46:28

+0

明白了。我通常使用它們,並且將來肯定會繼續使用它們。編輯:它看起來很奇怪,因爲它只是匆匆被扔在一起。將其設置爲0並非出於任何有目的的理由:> – catbat 2012-04-19 02:00:52

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

這非常有趣,我需要在.map上做一些閱讀,因爲我對它不是很熟悉,但它似乎是一個更簡單的方法。格拉西亞斯! – catbat 2012-04-19 02:07:55

+0

map(也被稱爲'collect')是一個修改數組副本的好方法。您提供了一個在每個元素上運行的代碼塊;塊的返回值將成爲副本中的替換元素。例如,要增加列表中的每個數字:'[1,2,3] .map {| x | x + 1}',它返回'[2,3,4]'。 – 2012-04-19 02:11:47

+0

看起來非常有用。再次感謝! – catbat 2012-04-19 02:19:09