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

Aug*_*sto 4 ruby string ruby-on-rails

9.3我有一种奇怪的行为,我无法理解为什么:

s = self.shopify_p
s.title
=> "Disco (Wholesale)"
Run Code Online (Sandbox Code Playgroud)

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

original_title = s.title
=> "Disco (Wholesale)" 
original_title[" (Wholesale)"] = ""
=> ""
Run Code Online (Sandbox Code Playgroud)

如果我这样做:

original_title
=> "Disco"
Run Code Online (Sandbox Code Playgroud)

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

s.title
=> "Disco"
Run Code Online (Sandbox Code Playgroud)

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

s.title应该仍然是"迪斯科(批发)"......或不?

小智 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> 
Run Code Online (Sandbox Code Playgroud)

你可以做的是

original_title = s.title.gsub(" (Wholesale)","")
Run Code Online (Sandbox Code Playgroud)


Ste*_*fan 6

original_title = s.title两者之后original_titles.title引用同一个对象.

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

original_title = s.title.dup
Run Code Online (Sandbox Code Playgroud)

dup→an_object

生成obj的浅表副本...

或者String.new:

original_title = String.new(s.title)
Run Code Online (Sandbox Code Playgroud)

new(str ="")→new_str

返回包含str副本的新字符串对象.


Pau*_*bel 3

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

如果 a、b、c 和 d 都指向同一个对象,则对任何对象的更改都将“更改”(通过它们可见)。

  a  b  c
   \ | /
   Object
     |
     d
Run Code Online (Sandbox Code Playgroud)

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

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"
Run Code Online (Sandbox Code Playgroud)

对于您的情况,@wlad 的 gsub (请注意,他没有使用 gsub!)建议似乎是一个不错的建议。

original_title = s.title.gsub(" (Wholesale)","")
Run Code Online (Sandbox Code Playgroud)