Bug? variable changes without assignment

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?

[[email protected] 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

[[email protected] 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???

[[email protected] ocr]# ruby --version
ruby 1.8.6 (2008-08-11 patchlevel 287) [x86_64-linux]

On Wed, Apr 21, 2010 at 5:37 PM, Bob G. [email protected] 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.

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?

On Wed, Apr 21, 2010 at 6:26 PM, Bob G. [email protected] 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.

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.

[[email protected] 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

[[email protected] 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’
[[email protected] ocr]#

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs