Bug? variable changes without assignment

Discussion in 'Ruby' started by Bob Gustafson, Apr 21, 2010.

  1. 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]
    --
    Posted via http://www.ruby-forum.com/.
    Bob Gustafson, Apr 21, 2010
    #1
    1. Advertising

  2. On Wed, Apr 21, 2010 at 5:37 PM, Bob Gustafson <> wrote:
    > 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.
    Jesús Gabriel y Galán, Apr 21, 2010
    #2
    1. Advertising

  3. 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?
    --
    Posted via http://www.ruby-forum.com/.
    Bob Gustafson, Apr 21, 2010
    #3
  4. On Wed, Apr 21, 2010 at 6:26 PM, Bob Gustafson <> wrote:
    > Jes=FAs Gabriel y Gal=E1n wrote:
    >
    >> 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.
    Jesús Gabriel y Galán, Apr 21, 2010
    #4
  5. 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]#

    --
    Posted via http://www.ruby-forum.com/.
    Bob Gustafson, Apr 21, 2010
    #5
    1. Advertising

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

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Replies:
    1
    Views:
    384
    Jason Whitlark
    Jul 25, 2003
  2. nagy
    Replies:
    36
    Views:
    980
    Terry Reedy
    Jul 20, 2006
  3. Chris
    Replies:
    34
    Views:
    1,483
  4. filmil
    Replies:
    11
    Views:
    1,229
    Mike Treseler
    May 25, 2007
  5. Derek Basch
    Replies:
    8
    Views:
    128
    Ben Morrow
    Aug 12, 2006
Loading...

Share This Page