Hello
I am new to ruby and looking for a brief explanation on why a code
sample
works in an unexpected way.
Beginning of code
def wipe_from( sentence )
sentence_new = sentence
while sentence_new.include? ‘(’
open = sentence_new.index( ‘(’ )
close = sentence_new.index( ‘)’, open )
sentence_new[open…close] = ‘’ if close
end
sentence_new
end
spoken = “I’m not happy with (nonsense) this moon.”
test = wipe_from( spoken )
puts spoken
puts test
End of code
I’d expect that the variable spoken would be unchanged because it’s
sentence_new that’s being modified. It works as expected if I use dup or
clone, but why is spoken being modified at all? Shouldn’t it just be
returning the value of sentence_new?
Brian
Ruby treats all variables as references to an object.
ie. if i say:
sentence = “my string”
you can think of it like this:
“my string” is stored as data somewhere in memory( let’s say memory slot
13)
then will hold the value 13. (the memory location that
contains it’s data)
so if you say:
sentence_new = sentence
then it will assign the value 13 to <sentence_new>
so now both <sentence_new> and refers to whatever is at
memory slot 13.
so now it doesn’t matter if you say:
sentence_new[open…close] = ‘’ OR
sentence[open…close] = ‘’
they’re both modifying the data at memory slot 13.
Hope that helps clear things up.
-Patrick
From: Brian R. [mailto:[email protected]]
def wipe_from( sentence )
sentence_new = sentence
if in doubt, insert
p sentence.object_id
p sentence_new.object_id
while sentence_new.include? ‘(’
open = sentence_new.index( ‘(’ )
close = sentence_new.index( ‘)’, open )
sentence_new[open…close] = ‘’ if close
end
sentence_new
end
spoken = “I’m not happy with (nonsense) this moon.”
test = wipe_from( spoken )
puts spoken
puts test
if in doubt, insert
p spoken.object_id
p test.object_id
# End of code
I’d expect that the variable spoken would be unchanged because it’s
sentence_new that’s being modified. It works as expected if I
variables are just references to objects. when you do
y = “test”
x = y
x and y now references to the original string object “test”
use dup or clone, but why is spoken being modified at all?
Shouldn’t it just be returning the value of sentence_new?
not ruby. use dup or clone to taste 
anyway, in ruby nothing is impossible. In fact, there are many better
ways 
in your case eg, you can use string#gsub
sample,
irb(main):001:0> spoken = “I’m not happy with (nonsense) this moon.”
=> “I’m not happy with (nonsense) this moon.”
irb(main):002:0> spoken_new = spoken.gsub(/(.*)/,“”)
=> “I’m not happy with this moon.”
irb(main):003:0> spoken_new
=> “I’m not happy with this moon.”
irb(main):004:0> spoken
=> “I’m not happy with (nonsense) this moon.”
hth.
kind regards -botp
Mmm, there’s only two types of operations in Ruby. Assignment, and
method calls.
sentence = “variable” is an assignment. The object_id of “variable” is
put inside a variable named
sentence[3] = ‘t’ is a method call. The method’s name is “[]=”, so
sentence does whatever the method is defined as:
sentence[3] = ‘t’ does the same thing as:
sentence.[]=(‘t’)
Assignment ALWAYS assigns a new object.
Method calls ALWAYS operates directly on the receiving object.
On Thu, Aug 14, 2008 at 10:20 PM, botp [email protected] wrote:
variables are just references to objects. when you do
y = “test”
x = y
x and y now references to the original string object “test”
Thanks so much for the help. What has been confusing is that the object
changes in this next bit of test code so that both variables reference
different objects:
Start of code that changes object
sentence = “first”
p sentence.object_id
sentence_new = sentence
p sentence_new.object_id
sentence = “second”
p sentence.object_id
p sentence_new.object_id
End of code
and I think that I figured out that the [] method doesn’t change the
object
referenced, but just the value of the object, while using = to assign a
new
value assigns a new object as well. Is that correct? Is there a way to
use =
without changing the object in the example above?
Start of code that preserves object
sentence = “test”
p sentence.object_id
sentence_new = sentence
p sentence_new.object_id
sentence[‘t’] = ‘p’
p sentence.object_id
puts sentence_new
puts sentence
End of code
Thanks again
Brian
From: Brian R. [mailto:[email protected]]
def wipe_from( sentence )
sentence_new = sentence
if in doubt, insert
p sentence.object_id
p sentence_new.object_id
while sentence_new.include? ‘(’
open = sentence_new.index( ‘(’ )
close = sentence_new.index( ‘)’, open )
sentence_new[open…close] = ‘’ if close
end
sentence_new
end
spoken = “I’m not happy with (nonsense) this moon.”
test = wipe_from( spoken )
puts spoken
puts test
if in doubt, insert
p spoken.object_id
p test.object_id
# End of code
I’d expect that the variable spoken would be unchanged because it’s
sentence_new that’s being modified. It works as expected if I
variables are just references to objects. when you do
y = “test”
x = y
x and y now references to the original string object “test”
use dup or clone, but why is spoken being modified at all?
Shouldn’t it just be returning the value of sentence_new?
not ruby. use dup or clone to taste 
anyway, in ruby nothing is impossible. In fact, there are many better
ways 
in your case eg, you can use string#gsub
sample,
irb(main):001:0> spoken = “I’m not happy with (nonsense) this moon.”
=> “I’m not happy with (nonsense) this moon.”
irb(main):002:0> spoken_new = spoken.gsub(/(.*)/,“”)
=> “I’m not happy with this moon.”
irb(main):003:0> spoken_new
=> “I’m not happy with this moon.”
irb(main):004:0> spoken
=> “I’m not happy with (nonsense) this moon.”
hth.
kind regards -botp