【问题标题】:Why is it replace not replace! for strings in ruby?为什么是替换而不是替换!对于红宝石中的字符串?
【发布时间】:2015-09-16 12:54:46
【问题描述】:

replace 改变当前字符串而不是返回一个新实例。为了与 Ruby 中的其他方法保持一致,它似乎应该被称为 replace! 这是一个错误/不一致还是我错过了什么?

【问题讨论】:

  • @sawa 他还提到他可能错过了一些东西......所以冷静:)
  • @sawa 我试图让我的问题的语气反映这一点。我问这个问题的真正原因是我想知道我误解了什么,因为 ruby​​ 是一般一致的。感谢 pyRabbit 的评论,我发现了 bang(!) 的含义。
  • 顺便说一句,有几种破坏性方法没有爆炸:clearconcatinsertprepend,......文档甚至提到了这一点:“通常,名称以“!”结尾的方法修改其接收者,而没有“!”的方法返回一个新字符串。但是,也有例外”

标签: ruby immutability


【解决方案1】:

来自 matz 的帖子https://www.ruby-forum.com/topic/176830#773946

砰(!)并不意味着“破坏性”,也不是没有它意味着非 破坏性的。 bang 标志的意思是“bang 版本更 比它的非爆炸对应物危险;小心处理”。由于 Ruby 有很多“破坏性”的方法,如果爆炸符号跟随你 看来,每个 Ruby 程序都会满是刘海,因此很丑。

所以最初的问题来自对 bang (!) 含义的误解。没有爆炸,因为只有一个 replace 方法才有意义,因此无需将其标记为“更危险”。

【讨论】:

  • 你明白这是对你的误解,因为你是 OP。您甚至没有在问题中写下您认为爆炸意味着破坏性。
  • 这会使您的问题更清楚,但请注意,这也会改变问题。
  • 我不确定。这个问题(如预期的那样)来自工作中的一些混乱。我明白了!表示对字符串的破坏性方法。这就是为什么它觉得replace 是不正确的。
【解决方案2】:

没有。每当您想要一个与另一个现有字符串没有任何关系的新字符串时,从现有字符串中创建新字符串是没有意义的。例如,假设有一个 String 方法 create_new_string 通过将内容替换为给定参数来从现有字符串中创建一个新的字符串实例,如下所示:

"foo".create_new_string("bar")
# => "bar" 

很容易看出这没有意义。您可以而且应该使用字符串文字创建一个新字符串:

"bar"
# => "bar"

因此,使用String 方法通过替换其内容来破坏性地创建新字符串是没有意义的;一个将替换字符串内容的有意义的方法应该破坏性地替换接收者字符串的内容并毫无意外地返回该字符串。因此,不需要爆炸。

【讨论】:

  • 为了清楚起见,我认为重要的是要注意这种方法不能比它已经具有的更具破坏性。这就是为什么没有“爆炸”对应物的原因。请参阅 Matz 的帖子ruby-forum.com/topic/176830#773946
  • @sawa 我明白为什么只有一个 replace 方法(你的回答总结得很好)。但令我惊讶的是,所有其他改变原地字符串的方法都以砰的一声结束。而这个没有。基本上我期待replace! 而不是replace,我想知道为什么不是这样。
  • 刚刚阅读了@pyRabbit 的答案,这对我来说更有意义。我没有意识到 bang 表示“比非 bang 版本更危险”。
  • @SteveB 是对的。 Matz 的帖子的 tl; 博士是“爆炸”不一定表示方法是否具有破坏性。他提出了一个很好的观点,如果是这样的话,Ruby 代码将被 bang 淹没。
  • @SteveB:“所有其他改变字符串的方法都以砰的一声结尾”——不正确:clearconcatforce_encodinginsertprependsetbyte<<[]= 也没有 bang 和修改接收器。其中几个也存在于ArrayHash,具有相同的语义。 Array 也有 poppushshiftunshift。然后是Kernel#exitKernel#exit!,它们与改变接收器无关。
猜你喜欢
  • 1970-01-01
  • 2013-12-28
  • 2019-10-23
  • 2022-01-21
  • 1970-01-01
  • 1970-01-01
  • 2015-08-13
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多