Use of dup to remove references

B

Brian Ross

[Note: parts of this message were removed to make it a legal post.]

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
 
P

Patrick Li

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.

Hope that helps clear things up.
-Patrick
 
B

botp

From: Brian Ross [mailto:p[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
 
B

Brian Ross

[Note: parts of this message were removed to make it a legal post.]

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
 
P

Patrick Li

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>

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.
 
P

Peña, Botp

From: Brian Ross [mailto:p[email protected]]=20
# def wipe_from( sentence )
# sentence_new =3D sentence

if in doubt, insert

p sentence.object_id
p sentence_new.object_id


# while sentence_new.include? '('
# open =3D sentence_new.index( '(' )
# close =3D sentence_new.index( ')', open )
# sentence_new[open..close] =3D '' if close
# end
# sentence_new
# end
# spoken =3D "I'm not happy with (nonsense) this moon."
# test =3D wipe_from( spoken )
# puts spoken
# puts test

if in doubt, insert

p spoken.object_id
p test.object_id
=20
# # End of code
#=20
# 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=20

variables are just references to objects. when you do

y =3D "test"
x =3D y

x and y now references to the original string object "test"

# use dup or clone, but why is spoken being modified at all?=20
# 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 =3D "I'm not happy with (nonsense) this moon."
=3D> "I'm not happy with (nonsense) this moon."

irb(main):002:0> spoken_new =3D spoken.gsub(/\(.*\)/,"")
=3D> "I'm not happy with this moon."

irb(main):003:0> spoken_new
=3D> "I'm not happy with this moon."

irb(main):004:0> spoken
=3D> "I'm not happy with (nonsense) this moon."

hth.
kind regards -botp
 

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,744
Messages
2,569,484
Members
44,903
Latest member
orderPeak8CBDGummies

Latest Threads

Top