catbat
catbat

Reputation: 93

Basic issue with variables

I feel like I'm missing something very, very fundamental, so, to avoid tearing out more hair, I come here to ask why p1, p1t and p1t2 are getting modified on with "hand = newgame.view p1". I don't even know why p1 is getting modified, so yeah I'm totally baffled here. Any help would be tremendously appreciated.

# 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 '----------------------------------'

output:

"----------------------------------"
"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"]]
"----------------------------------"

Upvotes: 1

Views: 46

Answers (3)

Mark Reed
Mark Reed

Reputation: 95242

FWIW, your view method could be simplified a lot:

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

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

This version doesn't modify anything, so avoids the issue.

Upvotes: 1

Sergio Tulentsev
Sergio Tulentsev

Reputation: 230276

Arrays are passed by reference, not copied. Check out this snippet.

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

Upvotes: 1

Ed Swangren
Ed Swangren

Reputation: 124622

You have defined a method view which takes a parameter hand (BTW, parens are nice, not sure why you always omit them in your code, even in the method signature). The view method modifies its argument hand. You call it as

hand = newgame.view p1

This, p1 is modified by the method view, and that's why it changes.

I'm also curious why you set p1 to 0... and then set it to an array of arrays. There is no reason to do that. Also, try to use descriptive variable names, for yourself as well as others.

Upvotes: 1

Related Questions