【问题标题】:How to replace 'nil' with a value using sub如何使用 sub 将“nil”替换为值
【发布时间】:2013-07-31 11:52:03
【问题描述】:

我正在尝试用 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

我错过了什么?

【问题讨论】:

  • 零就是零:没有什么可以替代的。
  • @dave: b.to_s.nil? => false
  • 显然,你把它变成了不是 nil 的东西——一个 nil 对象的字符串表示。我想我错过了你的观点。重要的是nil.nil?。仅仅因为你可以在某个东西的强保留中进行替换并不意味着它会反映在原始对象中——to_s 可以返回它想要的任何东西。
  • 我正在尝试用一个值(就地)替换一个 var。当 var 具有空字符串并且将 nil 转换为字符串(空字符串)时,我会看到不同的行为。
  • 因为nil 为零,而不是字符串。我不明白这个问题。如果你希望b 不是 nil,你需要设置它。 Nil 的 to_s 返回一个新字符串,其中包含“nil”。正如我所说,to_s 可以返回 anything,一般来说,对那个字符串做事不会影响底层对象。

标签: ruby string substitution


【解决方案1】:

为了帮助您了解正在发生的事情,让我们逐句按照您的代码进行说明:

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 返回的对象被更改(但随后被丢弃)。

【讨论】:

    【解决方案2】:

    你想初始化 b 吗?惯用的 Ruby 初始化方式是:

    b ||= "替换"

    【讨论】:

    • 不像我想的那样平常;)
    【解决方案3】:

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

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

    【讨论】:

      【解决方案4】:

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

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

      将帮助您,否则它将保留 nil 这是由于 to_s 提供了您的 b 对象的临时表示,因此 sub! 根本不会影响 b

      证据:

      s = "monkey"
      s.sub!('m', 'd')
      >> "donkey"
      

      【讨论】:

        【解决方案5】:

        改用以下内容:

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

        你使用什么版本的 Ruby?

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

        【讨论】:

        • 我没有做任何具体的事情。正在努力学习红宝石。就是这样。
        【解决方案6】:

        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?
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2011-10-10
          • 2012-08-02
          • 1970-01-01
          • 2020-12-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多