Reputation: 123
This code (in Ruby 1.9)
word = 'atf'
new_word = word
word[0] = 'w'
puts new_word
gives the response "wtf", this
word = 'ok'
new_word = word
word = 'wft'
puts new_word
gives the response "ok" which is much more what I'd expect. Is this a bug in Ruby or am I wrong in my expectation that changing word, however I change it, shouldn't change new_word.
Upvotes: 1
Views: 93
Reputation: 16732
As said in the other answers you are pointing to variables to the same string object.
''Please remmber'': Ruby never copies/duplicates an object just by assigning it (or returning, or passing to a function). So if you are coming from C/C++, Ruby only works with references/pointers. (And if you are coming from Java: the behavior is very similar to Java non-primitives).
for example:
a = [1, 2]
b = a
b << 3
puts a.inspect
# prints [1, 2, 3]
or even more confusing if you are not used to it:
def foo(x)
x << 3
return nil
end
a = [1, 2]
foo(a)
foo(a)
puts a.inspect
# prints [1, 2, 3, 3]
In some cases Ruby provides two methods of the same functionality, one which changes the actual object, the other returns a new object containing the changes.
For example String#gsub(from, to)
returns a new String containing these changes, on the other hand String#gsub!(from, to)changes the string itself. Another example would be
Array#rejectvs.
Array#reject!`
Object#dup
copies an object (but not its nesting objects).
Please note: in most cases not modifying a String is considered good style
Upvotes: 1
Reputation: 31077
The important thing to note is the meaning of:
new_word = word
The assignment does not copy the value of word
into new_word
. It sets makes the variable new_word
point to the same memory address as the variable word
.
Therefore, new_word[0] = 'x'
and word[0] = 'x'
will have the same effect on the value of both variables new_word
and word
.
You can fix the problem by doing either:
new_word = word.dup
or
new_word = word.clone
clone
and dup
create copies in memory of the value of the variable, and return a reference to that memory, which is then assigned to new_word
. There are differences between clone
and dup
but they're beyond the scope of your question.
Additionally, you will find that many languages function in this way. For instance, you can try the same semantics in C# or javascript, and see the same behavior.
Upvotes: 0
Reputation: 44080
word[0] = 'w'
is a method call on an object referenced by word
variable.
word = 'wft'
is variable assignment.
Upvotes: 1
Reputation: 87386
In the first example, there is only one actual string object, and you have two variable names that refer to it. Modifying the string therefore modifies each variable. You could instead do:
new_word = word.dup
to make a copy.
Upvotes: 3