Bug? variable changes without assignment

B

Bob Gustafson

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]
 
J

Jesús Gabriel y Galán

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
=A0 =A0constant =3D '31.12.2006'
puts "constant " + constant
=A0 =A0modify =3D '40.01'
puts "modify " + modify

=A0 variable =3D constant

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

puts variable.object_id
puts constant.object_id
=A0 variable[0..1] =3D modify[0..1]

This sends the message []=3D to the string object, which modifies the
string object contents.
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 =A0 =A0<<<---- Why does this change???

This is not a bug, it's the way objects and variables work in ruby.
When you do this:

variable =3D 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 []=3D, 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 =3D value
irb(main):005:2> end
irb(main):006:1> end
=3D> nil
irb(main):008:0> a =3D A.new "original value"
=3D> #<A:0xb7d4a280 @a=3D"original value">
irb(main):009:0> b =3D a
=3D> #<A:0xb7d4a280 @a=3D"original value">

At this point a and b reference the same object.

irb(main):010:0> a.a =3D "different value"
=3D> "different value"
irb(main):011:0> a
=3D> #<A:0xb7d4a280 @a=3D"different value">
irb(main):012:0> b
=3D> #<A:0xb7d4a280 @a=3D"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.
 
B

Bob Gustafson

Jesús Gabriel y Galán said:
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?
 
J

Jesús Gabriel y Galán

Jes=FAs Gabriel y Gal=E1n said:
This is not a bug, it's the way objects and variables work in ruby.
When you do this:

variable =3D 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 []=3D, 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 =3D 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.
 
B

Bob Gustafson

Jesús Gabriel y Galán said:
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]#
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

No members online now.

Forum statistics

Threads
473,999
Messages
2,570,243
Members
46,836
Latest member
login dogas

Latest Threads

Top