2015-02-06 62 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