0

我试图用使用 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

我错过了什么?

4

6 回答 6

3

为了帮助您了解正在发生的事情,让我们逐句遵循您的代码语句:

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被更改(但随后被丢弃)。

于 2013-07-31T12:04:06.703 回答
3

您是否要初始化 b?惯用的 Ruby 初始化方法是:

b ||= "替换"
于 2013-07-31T12:04:37.513 回答
2

无论您对 做什么b.to_s,它都是与 不同的对象b,因此b不会被修改,并且保持为nil,就像最初分配的那样。

并且没有办法nil使用gsub!. 该方法是在 上定义的String,而不是在 上NilClass。但是,您可以b通过执行重新分配给字符串b = whatever_string

于 2013-07-31T12:00:33.220 回答
2

您没有分配b给“已替换”的新值。

b = b.to_s.sub!(//,"replaced")

会帮助你,否则它会留下来nil这是由于提供了你的对象to_s的临时表示,因此根本不会影响。bsub!b

证据:

s = "monkey"
s.sub!('m', 'd')
>> "donkey"
于 2013-07-31T12:01:13.267 回答
0

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?
于 2013-07-31T11:54:47.010 回答
0

请改用以下内容:

irb(main):006:0> b = b.to_s.sub(//, "123")
    => "123"

你用的是什么版本的 Ruby?

顺便说一句,你能提供更多关于你在做什么的细节吗,因为这对我来说有点奇怪。也许我们会给你更合适的建议。

于 2013-07-31T11:56:28.717 回答