2012-07-13 98 views
2

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" 

我真的不明白這個......你能告訴我這裏發生了什麼嗎?

s.title應該仍然是「迪斯科(批發)」...或不是?

回答

3

ruby​​中的變量引用它們指向的對象,而不是默認複製它們。所以,如果你改變了基礎對象,任何改變都會顯示在任何包含對該對象引用的變量中。

如果a,b,c和d全部指向相同的對象,則任何將更改爲「更改」(可通過​​)所有這些對象。

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)","") 
+0

感謝您的出色答案! – Augusto 2012-07-14 14:47:48

8

這是因爲你正在訪問同一個對象。

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)","") 
+0

非常感謝你,我一直在使用紅寶石超過一年,但我仍然不知道這一點! – Augusto 2012-07-13 12:46:44

+0

如果你問我很奇怪的行爲。 – 2017-01-25 09:25:48

4

original_title = s.titleoriginal_titles.title引用相同的對象之後。

要真正複製字符串或者使用Object#dup

original_title = s.title.dup 

DUP→an_object

主要生產的OBJ淺表副本...

String.new

original_title = String.new(s.title) 

新(STR = 「」)→new_str

返回包含STR的副本的新的字符串對象。

+0

哇,謝謝!我真的不知道這個!現在它工作了!你知道有哪篇文章能深入解釋這個嗎? – Augusto 2012-07-13 12:47:44

+0

[編程Ruby - 類,對象和變量](http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_classes.html#S5) – Stefan 2012-07-13 12:54:37