为什么字符串替换会修改原始变量值?

时间:2012-07-13 12:35:28

标签: ruby-on-rails ruby string

9.3我的行为很奇怪,我无法理解为什么:

s = self.shopify_p
s.title
=> "Disco (Wholesale)"

现在我想要一个新的变量,其中s.title的内容没有“(批发)”部分。 所以我做了以下几点:

original_title = s.title
=> "Disco (Wholesale)" 
original_title[" (Wholesale)"] = ""
=> ""

现在,如果我这样做:

original_title
=> "Disco"

哪个好,但奇怪的是,似乎最后一个字符串替换影响了原来的s变量:

s.title
=> "Disco"

我真的无法理解这个......你能告诉我这里发生了什么吗?

标题应该仍然是“迪斯科(批发)”......或不是?

3 个答案:

答案 0 :(得分:9)

它是相同的,因为你正在访问同一个对象。

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> 

你可以做的是

original_title = s.title.gsub(" (Wholesale)","")

答案 1 :(得分:6)

original_title = s.title后,original_titles.title引用同一个对象。

要实际复制字符串,请使用Object#dup

original_title = s.title.dup
  

dup→an_object

     

生成 obj ...

的浅表副本

String.new

original_title = String.new(s.title)
  

new(str =“”)→new_str

     

返回一个新的字符串对象,其中包含 str 的副本。

答案 2 :(得分:3)

ruby​​中的变量引用它们指向的对象,而不是默认复制它们。因此,如果更改基础对象,则任何更改都将显示在包含对该对象的引用的任何变量中。

如果a,b,c和d都指向同一个对象,对any的更改将“更改”(通过)所有这些对象。

  a  b  c
   \ | /
   Object
     |
     d

如果你想保留原始值,你需要以某种方式创建一个新变量。

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"

对于你的案例@wlad的gsub(注意他没有使用gsub!)建议似乎是一个好的。

original_title = s.title.gsub(" (Wholesale)","")