John Coolidge John Coolidge - 1 year ago 65
Ruby Question

Why won't Ruby methods mutate the original array?

I'm creating a game so as to practice some basic Ruby. In my blackjack game, I've created a deck of cards to draw from. The only way that I've managed to mix up the array, draw from that array and remove two cards from the original cards array is as follows:

player_cards = cards.shuffle!.shift(2)

I tried to use shift and pop along with shuffle like so:

player_cards = cards.shuffle.shift
player_cards = cards.shuffle.pop

In IRB, if I use pop and shift without shuffle, the array I'm trying to pull from (array of hashes) removes those cards from the deck. As soon as I add shuffle, the cards are no longer removed from the deck permanently. I have to use shuffle! in order to complete my task.

What I want to know is, why doesn't pop and shift work as expected with shuffle? My rudimentary understanding of chaining in Ruby is that the cards array is first shuffled and returned and then an element in the array is removed.

My only thought as to what my error might be is that shuffle shuffles the array and returns a shuffled array, but not the original cards array. When I pop or shift one or two cards from that shuffled array, it's the array returned by shuffle, not the original array of cards. Is that correct?

Answer Source

There is a significant difference between cards.shuffle and cards.shuffle! (banged version.)

The former creates a new array, and the latter mutates the original one.

That said, your latter code shifts and pops from the copy of the original array, produced by shuffle.