Reputation: 1150
9.3 I'm getting a strange behaviour and I cannot understand why:
s = self.shopify_p
s.title
=> "Disco (Wholesale)"
Right now I'd like to have a new variable with the content of s.title without the " (Wholesale)" part. So I do the following:
original_title = s.title
=> "Disco (Wholesale)"
original_title[" (Wholesale)"] = ""
=> ""
Now if I do:
original_title
=> "Disco"
Which is ok but the strange thing is that it seems that the last string replace affected even the original s variable:
s.title
=> "Disco"
I really cannot understand this...can you tell me what is happening here?
s.title should still be "Disco (Wholesale)"...or not?
Upvotes: 5
Views: 2631
Reputation: 114178
After original_title = s.title
both original_title
and s.title
reference the same object.
To actually copy the string either use Object#dup
:
original_title = s.title.dup
dup → an_object
Produces a shallow copy of obj…
or String.new
:
original_title = String.new(s.title)
new(str="") → new_str
Returns a new string object containing a copy of str.
Upvotes: 7
Reputation: 27222
Variables in ruby reference the objects they point to rather than copying them by default. So, if you change the underlying object, any changes will show up in any variables that contain a reference to that object.
If a, b, c and d all point to the same object, changes to any will "change" (be visible through) all of them.
a b c
\ | /
Object
|
d
If you want to keep your original value you'll need to somehow create a new variable.
irb(main):001:0> a = "Foo"
=> "Foo"
irb(main):002:0> b = a
=> "Foo"
irb(main):003:0> a << " Bar"
=> "Foo Bar"
irb(main):004:0> b
=> "Foo Bar"
irb(main):005:0> a
=> "Foo Bar"
irb(main):006:0> a += " Baz"
=> "Foo Bar Baz"
irb(main):007:0> a
=> "Foo Bar Baz"
irb(main):008:0> b
=> "Foo Bar"
For your case @wlad's gsub (note that he didn't use gsub!) suggestion seems like a good one.
original_title = s.title.gsub(" (Wholesale)","")
Upvotes: 3
Reputation: 579
It is the same because you're accessing the same object.
irb(main):006:0> x = "aaaa"
=> "aaaa"
irb(main):007:0> y = x
=> "aaaa"
irb(main):008:0> x.object_id
=> 70358166435920
irb(main):009:0> y.object_id
=> 70358166435920
irb(main):010:0>
What you could do instead is
original_title = s.title.gsub(" (Wholesale)","")
Upvotes: 10