r0b0t
r0b0t

Reputation: 23

Ruby variables managment issue

I'm trying to figure out why the following codes doesn't return the same result:

CODE 1

p0 = "hello"
a = []
b = p0
1.upto(5) do |i|
  b.insert(2,"B")
  a.push b
end

a => ["heBBBBBllo", "heBBBBBllo", "heBBBBBllo", "heBBBBBllo", "heBBBBBllo"]

CODE 2

p0 = "hello"
a = []
b = p0
1.upto(5) do |i|
  b.insert(2,"B")
  a.push b.inspect
end

a => ["\"heBllo\"", "\"heBBllo\"", "\"heBBBllo\"", "\"heBBBBllo\"", "\"heBBBBBllo\""]

What I need is the Code 2's result, but I don't need the escaped char like the inspect method does.

Honestly, I really don't understand why with the inspect method works, and why in the code 1 doesn't. It seems like that in code 1, "b" is used as a pointer, and every time it's updated, all the "linked"-b are updated.

Any clue??

thank you in advance.

Upvotes: 2

Views: 52

Answers (4)

Max
Max

Reputation: 22325

It seems like that in code 1, "b" is used as a pointer, and every time it's updated, all the "linked"-b are updated.

Correct! In the first case, you're pushing b into the array five times, so the result is that a contains five pointers to b. In the second case you're pushing b.inspect - which is a different object from b.

The easiest way to fix your first example would be to call a.push b.dup instead, which creates a duplicate of b which won't be affected by future changes to b.

Upvotes: 0

whooops
whooops

Reputation: 935

'b' is a string, which is an object. When you insert a letter, it modifies the object.

In CODE 1, that same object b is being pushed into the array multiple times, and modified multiple times.

However, b.inspect returns a new string. So in CODE 2, you push a new string into the array each iteration, and that new string is a snapshot of how 'b' looked at the time.

You could use a.push b.dup instead, which creates a copy of b without changing the format.

Upvotes: 0

Andrew Kolesnikov
Andrew Kolesnikov

Reputation: 1893

p0 = "hello"
a = []
b = p0

1.upto(5) do |i|
  b.insert(2,"B")
  a.push b.clone
end

Upvotes: 1

Dave Newton
Dave Newton

Reputation: 160191

In code 1 you're pushing references to the same object. The array will contain multiple references to the same thing.

In code 2 you're pushing the inspect output at a distinct moment in time. The array will contain a history of inspect's returned strings.

Upvotes: 3

Related Questions