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?
Value of the StringValue is changed. It will run with the new value being stored in the argument object, instead of a string representing the property being changed. This event, like other changed events, can be used to track when an StringValue changes and to track the different values that it may change to.
Unless you assign the variable to be itself with a string method modifying it, then it will remain the same.
The replace() method searches a string for a value or a regular expression. The replace() method returns a new string with the value(s) replaced. The replace() method does not change the original string.
Strings in Java are immutable - when you call replace , it doesn't change the contents of the existing string - it returns a new string with the modifications.
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)","")
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.
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)","")
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With