# Bug? variable changes without assignment

**URL:** <https://www.ruby-forum.com/t/bug-variable-changes-without-assignment/187321>\
**Category:** Ruby\
**Created:** [April 21, 2010, 5:36pm UTC](https://www.ruby-forum.com/t/bug-variable-changes-without-assignment/187321 "2010-04-21T17:36:53Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![efilm66](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/35a633/32.png) [@efilm66](https://www.ruby-forum.com/u/efilm66)\
**Post date:** [April 21, 2010, 5:36pm UTC](https://www.ruby-forum.com/t/bug-variable-changes-without-assignment/187321/1 "2010-04-21T17:36:53Z")

</div>

I seem to have uncovered a bug. The program below defines a series of  
variables, named constant, modify, and variable. The constant should  
remain constant, but instead, it changes - even without an assignment.  
How does this happen?

[root@hoho4 ocr]# cat test.rb  
constant = ‘31.12.2006’  
puts "constant " + constant  
modify = ‘40.01’  
puts "modify " + modify

variable = constant

puts "variable " + variable  
puts "constant " + constant

variable[0…1] = modify[0…1]

puts "variable " + variable  
puts "constant " + constant

[root@hoho4 ocr]# ruby test.rb  
constant 31.12.2006  
modify 40.01  
variable 31.12.2006  
constant 31.12.2006  
variable 40.12.2006  
constant 40.12.2006 \<\<\<---- Why does this change???

[root@hoho4 ocr]# ruby --version  
ruby 1.8.6 (2008-08-11 patchlevel 287) [x86\_64-linux]

---

<div class="post-metadata">

**Author:** ![efilm66](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/35a633/32.png) [@efilm66](https://www.ruby-forum.com/u/efilm66)\
**Post date:** [April 21, 2010, 5:48pm UTC](https://www.ruby-forum.com/t/bug-variable-changes-without-assignment/187321/2 "2010-04-21T17:48:24Z")

</div>

On Wed, Apr 21, 2010 at 5:37 PM, Bob G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> variable = constant
> 
> puts "variable " + variable  
> puts "constant " + constant

puts variable.object\_id  
puts constant.object\_id

> variable[0…1] = modify[0…1]

This sends the message []= to the string object, which modifies the  
string object contents.

> constant 40.12.2006 \<\<\<---- Why does this change???  
> This is not a bug, it’s the way objects and variables work in ruby.  
> When you do this:

variable = constant

you are saying that variable now references the same object that  
constant references. So any message sent through variable or constant  
is sent to the same string object. If that message is a destructive  
message (like []=, or \<\<, or sub!), the object is changed and both  
variables will see the change since they are referencing the same  
object.

Check this simpler example

irb(main):001:0\> class A  
irb(main):002:1\> attr\_accessor :a  
irb(main):003:1\> def initialize value  
irb(main):004:2\> @a = value  
irb(main):005:2\> end  
irb(main):006:1\> end  
=\> nil  
irb(main):008:0\> a = A.new “original value”  
=\> #\<A:0xb7d4a280 @a=“original value”\>  
irb(main):009:0\> b = a  
=\> #\<A:0xb7d4a280 @a=“original value”\>

At this point a and b reference the same object.

irb(main):010:0\> a.a = “different value”  
=\> “different value”  
irb(main):011:0\> a  
=\> #\<A:0xb7d4a280 @a=“different value”\>  
irb(main):012:0\> b  
=\> #\<A:0xb7d4a280 @a=“different value”\>

so modifying the object through a means that we modify the same object  
referenced by b, because there’s only one object.

Hope this clarifies,

Jesus.

---

<div class="post-metadata">

**Author:** ![efilm66](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/35a633/32.png) [@efilm66](https://www.ruby-forum.com/u/efilm66)\
**Post date:** [April 21, 2010, 6:25pm UTC](https://www.ruby-forum.com/t/bug-variable-changes-without-assignment/187321/3 "2010-04-21T18:25:39Z")

</div>

JesÃºs Gabriel y GalÃ¡n wrote:

> This is not a bug, it’s the way objects and variables work in ruby.  
> When you do this:
> 
> variable = constant
> 
> you are saying that variable now references the same object that  
> constant references. So any message sent through variable or constant  
> is sent to the same string object. If that message is a destructive  
> message (like []=, or \<\<, or sub!), the object is changed and both  
> variables will see the change since they are referencing the same  
> object.

Ok, good to know that it is not a bug.

However, what is the syntax for an assignment where variable and  
constant do NOT refer to the same object?

---

<div class="post-metadata">

**Author:** ![efilm66](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/35a633/32.png) [@efilm66](https://www.ruby-forum.com/u/efilm66)\
**Post date:** [April 21, 2010, 7:00pm UTC](https://www.ruby-forum.com/t/bug-variable-changes-without-assignment/187321/4 "2010-04-21T19:00:24Z")

</div>

On Wed, Apr 21, 2010 at 6:26 PM, Bob G. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> > message (like []=, or \<\<, or sub!), the object is changed and both  
> > variables will see the change since they are referencing the same  
> > object.
> 
> Ok, good to know that it is not a bug.
> 
> However, what is the syntax for an assignment where variable and  
> constant do NOT refer to the same object?

Then what object do you want the second variable to refer to?  
If you want a duplicate of the object:

variable = constant.dup

is a usual idiom. Be careful when you deal with arrays this way,  
because an array is just a bunch of references, so even if you dup the  
array, the objects contained will be the same ones (dup performs a  
shallow copy).

Jesus.

---

<div class="post-metadata">

**Author:** ![efilm66](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/e/35a633/32.png) [@efilm66](https://www.ruby-forum.com/u/efilm66)\
**Post date:** [April 21, 2010, 7:12pm UTC](https://www.ruby-forum.com/t/bug-variable-changes-without-assignment/187321/5 "2010-04-21T19:12:07Z")

</div>

JesÃºs Gabriel y GalÃ¡n wrote:

> variable = constant.dup

OK, got it. I modified my program and I get what I want now. Thanks  
much.

[root@hoho4 ocr]# cat test.rb  
constant = ‘31.12.2006’  
puts "constant " + constant  
modify = ‘40.01’  
puts "modify " + modify

variable = constant.dup \<\<\<---- Added the .dup

puts "variable " + variable  
puts "constant " + constant

variable[0…1] = modify[0…1]

puts "variable " + variable  
puts "constant " + constant

[root@hoho4 ocr]# ruby test.rb  
constant 31.12.2006  
modify 40.01  
variable 31.12.2006  
constant 31.12.2006  
variable 40.12.2006  
constant 31.12.2006 \<\<— OK, it stays ‘constant’  
[root@hoho4 ocr]#
