As a novice it's probably something about Ruby I missed, but for the life of me I don't understand this result. So I have this simple function:
#return has not purpose here
Now I have this simple few sets.
s1 = 'abc'
s2 = s1
s2 = crazyfunc(str2)
Why in the world is s1 affected by crazyfunc? So doing this instead:
return s.gsub('a', 'b')
doesn't change str1, so I figure it's got to do with what the inplace gsub is doing. But I still don't get the logic of why str1 would be changed.
String assignment in Ruby doesn't implicitly copy the string. You are simply assigning another reference to it. If you want to copy the string, use clone.
To demonstrate, you can check object IDs:
ree-1.8.7-2010.02 > a = "foo" => "foo" ree-1.8.7-2010.02 > b = a => "foo" ree-1.8.7-2010.02 > a.object_id => 81728090 ree-1.8.7-2010.02 > b.object_id => 81728090
b have the same object ID, you know they're the same object. If you want to modify
b as a copy of
a, you can either use methods which return a new string (like
gsub rather than
gsub!), or you can use
b = a.clone, and then operate on
ree-1.8.7-2010.02 > a = "foo" => "foo" ree-1.8.7-2010.02 > b = a.clone => "foo" ree-1.8.7-2010.02 > a.object_id => 81703030 ree-1.8.7-2010.02 > b.object_id => 81696040 ree-1.8.7-2010.02 > b.gsub! "f", "e" => "eoo" ree-1.8.7-2010.02 > a => "foo" ree-1.8.7-2010.02 > b => "eoo"
Or more simply:
ree-1.8.7-2010.02 > a = "foo" => "foo" ree-1.8.7-2010.02 > b = a.gsub("f", "e") => "eoo" ree-1.8.7-2010.02 > puts a, b foo eoo
You are running into the fact that everything in Ruby is an object, and that variables are just object references.
When you assign str1 = to str2, you are actually pointing them at the same object. When you then change the object pointed to by str2, you are also changing the object pointed to by str1.
In your original crazyfunc, you modify the string, return the modified string, and then change the value of the object pointed to by str2 - and str1, since they point to the same object.
s1 = 'abc' s2 = s1 s2 = crazyfunc(str2)
B = A
C = B
A is A, and B equals A and C equals B. If you change B it doesn't affect A but affects C. See how it cascades down. The variables you list are just pointers.
So you only have 1 master variable here and you need to declare two.