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?
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 <sentence> 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 <sentence> 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.
# 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
···
From: Brian Ross [mailto:p.brian.ross@gmail.com]
#
# 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."
# 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
···
From: Brian Ross [mailto:p.brian.ross@gmail.com]
#
# 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."
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
···
On Thu, Aug 14, 2008 at 10:20 PM, botp <botpena@gmail.com> 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"