Ruby on rails 在ruby中使用gsub函数替换word

Ruby on rails 在ruby中使用gsub函数替换word,ruby-on-rails,ruby,gsub,Ruby On Rails,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",

我试图用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
类测试“替换此ID1”,
WAY=>“替换此ID2和ID3”,
DELTA=>“替换此ID4”
}
结束
另一个_model.rb

class Check < ActiveRecord::Base
  Test::BODY[2].gsub!("ID2", self.id).gsub!("ID3", self.name)
end
类检查
啊,我找到了<代码>gsub是一种非常奇怪的方法。首先,它在适当的位置替换字符串,因此它实际上修改了字符串。其次,当没有进行替换时,它返回
nil
。这一切都归结为你所犯的错误

第一次执行该调用时,它会修改分配给常量的字符串,因此它的内容为“替换此3和名称”。当您再次尝试运行它时,第一个
gsub
将无法找到它正在查找的字符串,因此将返回
nil
。然后在nil上执行第二个
gsub


取决于如何解决这个问题——这完全取决于你想要达到的目标。对我来说,更改其他类常量(破坏封装)有些冒险。如果您只想在不修改原始字符串的情况下获得结果,请使用
gsub
(no bang)。或者更好的方法是,将这些字符串转换成一个方法,并使用插值而不是替换。

如果字符串只是模式,则应该在使用之前替换它们。更好的方法是字符串插值

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

正如@Broisasze所说,您不应该更改其他类的常量或同一类本身的常量,最后它们是常量。

实际上,您正在使用gsub的字符串有时为零,这就是它抛出错误的原因<代码>测试::BODY[2]在某些情况下具有零值。@Fietsband-
WAY
是一个常数,等于2。@broiSatse-Hmm-oops,错过了那个部分。删除了我的评论,因为它是不相关的。谢谢@nafaa,我正在用新的源代码测试它,它工作到现在为止,尽管这是一个很好的答案,我不会称之为
gsub行为怪异。1.该行为在中有明确描述。2.这是一种变异接收器的方法。因此,没有理由返回对象,因为您已经拥有它。相反,它会返回一个真实或虚假的值,以向您提供有关是否进行了更改的反馈。为方便起见,thuthy值设置为
self
(也称为接收方,也称为字符串)。
str = "%{num1} / %{num1} = 1"
str % {num1: 3} # 3 / 3 = 1