不应该force_encoding是force_encoding!在红宝石?

时间:2018-01-04 13:45:58

标签: ruby

我只是想知道String方法force_encoding,因为它改变了给定字符串的编码,而不是它的副本,而应该命名为force_encoding!

更新以澄清我追求的答案: 我在这里缺少一些常规或一般的ruby特性,这可能解释了看似不一致的命名吗?

2 个答案:

答案 0 :(得分:5)

与流行的看法相反,许多误导性的初学者和#39;红宝石指南,爆炸方法意味着"这种方法会改变对象"。

对bang方法的约定的更好解释是"这是其非爆炸对应物的更危险版本"。

例如:

  • String#gsub!是"危险"版本String#gsub,因为它会改变对象。
  • ActiveRecord::Base#save!是"危险"版本ActiveRecord::Base#save,因为如果验证失败,会引发异常
  • exit!是"危险" exit的版本,因为前者立即退出,而后者实际上raises an exception - 可以在代码中的其他地方获救。

此外,请注意,有很多ruby方法变异对象,但不是方法。例如,String#deleteArray#pop

This article详细介绍了此事。

所以,(警告:自以为是的回应!)我认为:

  1. String#force_encoding是一种非爆炸方法。这与该语言中的其他约定并不完全不一致。
  2. 如果这是一个爆炸方法,它需要一个非爆炸对应的一致性。
  3. 我个人认为,非变异String#force_encoding的用例很常见,足以保证其创建。在极少数情况下,您确实想要这样做,您可以写下:string.dup.force_encoding(...)

答案 1 :(得分:2)

尽管有一个共同的假设,爆炸方法不一定会改变他们的接收器,你也不能认为非爆炸方法不会改变他们的接收器。例如,例如Array#popArray#clear

相反,带有拖尾的方法表明该方法是危险的"某种程度上来说。特别是在Ruby核心中,通常期望对于每个爆炸方法总是存在不那么危险的非爆炸方法。

有关详细信息,请参阅有关该主题的更一般问题的答案:Why are exclamation marks used in Ruby methods?