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]
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.
[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]#