noname
noname

Reputation: 35

Why a new call of a method with exclamation mark affects all previous calls of that method?

I'm sorry if this is a duplicate - I couldn't find anything similar in the existing posts.

I understand the difference between methods like shuffle and shuffle!. However, I am confused why calling the method more than once would result in changing the variables of all objects that previously referred to it? I'd expect once we apply a method, that the variable gets a value and we're done with it. Not that it continues to refer to the method call and the argument passed and that it would get re-evaluated later on.

I thought it's best to demonstrate with an example:

irb(main):001:1* def shuffle(arr)
irb(main):002:1*   arr.shuffle!
irb(main):003:0> end
=> :shuffle
irb(main):004:0> arr = [1,2,3,4]
=> [1, 2, 3, 4]
irb(main):005:0> one = shuffle(arr)
=> [4, 2, 3, 1]
irb(main):006:0> two = shuffle(arr)
=> [1, 2, 4, 3]
irb(main):007:0> one
=> [1, 2, 4, 3]

So, here I'd expect one to stay [4, 2, 3, 1]. However, with each new call, all previous ones would get equated to the latest result of the method call. I realise it should have something to do with calling it with the same argument arr, but still doesn't quite make sense.

Upvotes: 0

Views: 74

Answers (1)

Stefan
Stefan

Reputation: 114188

Array#shuffle! shuffles the array in-place and returns its receiver:

ary = [1, 2, 3, 4]
ary.equal?(ary.shuffle!) #=> true

Assigning the result from shuffle! to another variable doesn't change this. It merely results in two variables referring to the same array:

a = [1, 2, 3, 4]
b = a.shuffle!

a #=> [2, 4, 1, 3]
b #=> [2, 4, 1, 3]

a.equal?(b) #=> true

You probably want a new array. That's what Array#shuffle (without !) is for:

a = [1, 2, 3, 4]
b = a.shuffle

a #=> [1, 2, 3, 4]
b #=> [2, 4, 1, 3]

Even if shuffle returns the element in the original order, you'll get another array instance:

a = [1, 2, 3, 4]
b = a.shuffle until b == a

a #=> [1, 2, 3, 4]
b #=> [1, 2, 3, 4]

a.equal?(b) #=> false

Upvotes: 1

Related Questions