在 ruby 中使用 gsub 函数替换单词
Replace word using gsub function in ruby
我正在尝试用 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
另一个_model.rb
class Check < ActiveRecord::Base
Test::BODY[2].gsub!("ID2", self.id).gsub!("ID3", self.name)
end
啊,找到了! gsub!
是一个很奇怪的方法。首先,它替换了字符串,所以它实际上修改了你的字符串。其次,它 returns nil
当没有进行替换时。这一切都归结为您遇到的错误。
第一次执行该调用时,它会修改分配给常量的字符串,因此它显示为 "replace this 3 and name"
。当您第二次尝试 运行 时,第一个 gsub
将无法找到它正在寻找的字符串,因此 return nil
也会如此。然后在 nil 上执行第二个 gsub
。
关于如何解决它 - 这完全取决于您要实现的目标。对我来说,更改其他 class 常量(破坏封装)有点冒险。如果您只想获得结果而不修改原始字符串,请使用 gsub
(没有爆炸)。或者更好的是,将这些字符串转换为方法并使用插值而不是替换。
如果字符串只是模式,则应在使用前将其替换。更好的方法是字符串插值。
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
这将更改字符串中散列键的每个外观
例如:
str = "%{num1} / %{num1} = 1"
str % {num1: 3} # 3 / 3 = 1
就像@BroiSatse 说的,你不应该改变其他 classes 的常量或在同一个 class 本身内,最后它们是常量。
我正在尝试用 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
另一个_model.rb
class Check < ActiveRecord::Base
Test::BODY[2].gsub!("ID2", self.id).gsub!("ID3", self.name)
end
啊,找到了! gsub!
是一个很奇怪的方法。首先,它替换了字符串,所以它实际上修改了你的字符串。其次,它 returns nil
当没有进行替换时。这一切都归结为您遇到的错误。
第一次执行该调用时,它会修改分配给常量的字符串,因此它显示为 "replace this 3 and name"
。当您第二次尝试 运行 时,第一个 gsub
将无法找到它正在寻找的字符串,因此 return nil
也会如此。然后在 nil 上执行第二个 gsub
。
关于如何解决它 - 这完全取决于您要实现的目标。对我来说,更改其他 class 常量(破坏封装)有点冒险。如果您只想获得结果而不修改原始字符串,请使用 gsub
(没有爆炸)。或者更好的是,将这些字符串转换为方法并使用插值而不是替换。
如果字符串只是模式,则应在使用前将其替换。更好的方法是字符串插值。
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
这将更改字符串中散列键的每个外观
例如:
str = "%{num1} / %{num1} = 1"
str % {num1: 3} # 3 / 3 = 1
就像@BroiSatse 说的,你不应该改变其他 classes 的常量或在同一个 class 本身内,最后它们是常量。