2015-02-06 42 views
4

我想用ruby中的gsub函數替換字符串中的某個單詞,但有時可以正常工作,並且在某些情況下會出現此錯誤?有任何問題,這種格式在ruby中用gsub函數替換單詞

NoMethodError (undefined method `gsub!' for nil:NilClass): 

model.rb

class Test < ActiveRecord::Base 
    NEW = 1 
    WAY = 2 
    DELTA = 3 

    BODY = { 

    NEW => "replace this ID1", 
    WAY => "replace this ID2 and ID3", 
    DELTA => "replace this ID4" 
    } 
end 

another_model.rb

class Check < ActiveRecord::Base 
    Test::BODY[2].gsub!("ID2", self.id).gsub!("ID3", self.name) 
end 
+1

實際上你使用gsub的字符串是零,有時這就是它拋出錯誤的原因。 'Test :: BODY [2]'在某些情況下具有零值。 – Deep 2015-02-06 10:32:35

+1

@Fietsband - 'WAY'是一個常數等於2. – BroiSatse 2015-02-06 10:34:21

+0

@broiSatse嗯哎呀,錯過了那部分。刪除了我的評論,因爲它是無關緊要的。 – Biketire 2015-02-09 12:47:49

回答

4

啊,我找到了! gsub!是一個非常奇怪的方法。首先,它替換了字符串,所以它實際上修改了你的字符串。其次,當沒有替換時,它返回nil。這一切都歸結爲你得到的錯誤。

第一次執行該調用時,它會修改分配給常量的字符串,因此它會顯示爲"replace this 3 and name"。當你嘗試第二次運行它時,第一個gsub將無法找到它正在查找的字符串,因此將返回nil。第二個gsub然後在零上執行。

關於如何解決它 - 這一切都取決於你想要實現的。對我而言,改變其他類常量(中斷封裝)有點冒險。如果您只是想在不修改原始字符串的情況下得到結果,請使用gsub(無砰砰聲)。或者甚至更好,將這些字符串轉換爲方法並使用插值而不是替換。

2

如果字符串只是模式,那麼在使用之前應該將其替換。更好的方法是字符串插值。

class Test < ActiveRecord::Base 
    # Here use symbols instead, because symbols themselfs are immutable 
    # so :way will always equal :way 
    BODY = { 
    :new => "replace this %{ID1}", 
    :way => "replace this %{ID2} and %{ID3}", 
    :delta => "replace this %{ID4}" 
    }  
end 
# HERE you should create another constant based on the 
# Test class constants 
class Check < ActiveRecord::Base 
    BODY = { 
     :way => Test::BODY[:way] % {ID2: self.id, ID3: self.name} 
    } 

# Or you can make it a method 
def self.body 
    Test::BODY[:way] % {ID2: self.id, ID3: self.name} 
end 
end 

這將改變哈希鍵的每apearance串

例如:其他類的或內

str = "%{num1}/%{num1} = 1" 
str % {num1: 3} # 3/3 = 1 

而像@BroiSatse說,你不應該改變的常量同一類本身,最後它們是常量。

+0

謝謝@nafaa,我正在測試這個新源,到目前爲止它的工作情況 – django 2015-02-07 07:37:23