我试图用使用 sub 的东西代替 nil 值,但它没有发生。我哪里错了。
a=""
a.sub!(//,"replaced")
puts a #=> "replaced"
b=nil
b.to_s.sub!(//,"replaced") #tried => (b.to_s).sub!(//,"replaced") but didnt work
puts b #=> nil
我错过了什么?
我试图用使用 sub 的东西代替 nil 值,但它没有发生。我哪里错了。
a=""
a.sub!(//,"replaced")
puts a #=> "replaced"
b=nil
b.to_s.sub!(//,"replaced") #tried => (b.to_s).sub!(//,"replaced") but didnt work
puts b #=> nil
我错过了什么?
为了帮助您了解正在发生的事情,让我们逐句遵循您的代码语句:
a="" # create a new string object (the empty string), assign it to a
a.sub!(//,"replaced") # sub! changes this very string object
puts a #=> "replaced" # the changed string is printed
b=nil # we assign nil to b
b.to_s.sub!(//,"replaced") # this is actually two steps
# nil.to_s creates a new string object "" (the empty string)
# .sub! modifies that new string object in place
# the edited string is not assigned to anything, it will be garbage collected later
puts b #=> nil # b is still assigned to nil
我们观察到它b
本身永远不会被 改变sub!
。只有返回的对象b.to_s
被更改(但随后被丢弃)。
您是否要初始化 b?惯用的 Ruby 初始化方法是:
b ||= "替换"
无论您对 做什么b.to_s
,它都是与 不同的对象b
,因此b
不会被修改,并且保持为nil
,就像最初分配的那样。
并且没有办法nil
使用gsub!
. 该方法是在 上定义的String
,而不是在 上NilClass
。但是,您可以b
通过执行重新分配给字符串b = whatever_string
。
您没有分配b
给“已替换”的新值。
b = b.to_s.sub!(//,"replaced")
会帮助你,否则它会留下来nil
这是由于提供了你的对象to_s
的临时表示,因此根本不会影响。b
sub!
b
证据:
s = "monkey"
s.sub!('m', 'd')
>> "donkey"
nil
和空字符串不是一回事,nil
不是字符串,因此它没有sub!
方法。但是nil.to_s
给出了空字符串,并且您的代码在这里可以正常工作。
irb(main):007:0> b=nil
=> nil
irb(main):008:0> b.to_s.sub!(//,"replaced")
=> "replaced"
您的代码不起作用,因为您没有将结果分配回b
:
b = nil
b = b.to_s.sub(//,"replaced")
puts b
您需要这样做,因为 to_s 创建了 的副本b
,它在任何地方都没有被引用,那就是 sub! 变化。
另一种解决方案是检查 b 是否为 nil,并将其设置为 "":
b = "" if b.nil?
请改用以下内容:
irb(main):006:0> b = b.to_s.sub(//, "123")
=> "123"
你用的是什么版本的 Ruby?
顺便说一句,你能提供更多关于你在做什么的细节吗,因为这对我来说有点奇怪。也许我们会给你更合适的建议。