为什么 bang 方法在 Ruby 中很危险?

Why are bang methods dangerous in Ruby?

我最近在重新学习Ruby,this页面说通常bang方法是危险的,但没有说明原因。为什么 bang 方法很危险?

不,这并不危险。 Bang 方法只是意味着它们正在修改对象本身,你应该小心。

您参考的页面包括:

Normally for the built-in classes, dangerous usually (although not always) means this method, unlike its non-bang equivalent, permanently modifies its receiver.

"dangerous"在标准库和普通gem中有两种广泛的含义:

  1. 方法改变接收者,而不是return复制接收者。示例:Array#map!

  2. 如果无法执行其主要功能,方法将引发异常。示例:ActiveRecord::Base#save!ActiveRecord::Base#create!。例如,如果一个对象无法保存(因为它无效或其他原因),save! 将引发错误,而 save 将 return false.

我通常在我的代码中添加第三个含义:

  1. 方法会立即将数据持久化到数据库中,而不是仅仅更改一些属性并希望稍后有人保存该对象。示例:假设 Article#approve!

惯例是这样的:

  • 首先,只有当您有同名的非 bang 替代方法时,您才创建 bang 方法。
  • 其次-是的,这意味着这个版本是"more dangerous"。正如您自己所说,这是一个非常模糊的术语。
  • 在很多标准库中,它会就地修改一个对象,而不是创建一个新对象。如果调用不需要任何修改,有时它会 return nil 而不是对象。
  • 在 rails 中,bang 方法通常会引发异常,而不是 returning nil.

Why are bang methods dangerous?

因为这是命名约定:如果有两种方法做同样的事情,那么你将它们命名为相同的名称,但更令人惊讶或更危险的方法会得到爆炸。

例如Process::exit and Process::exit!都退出当前运行Ruby进程,但是bang版本会跳过运行所有可能安装的退出处理程序,等等,例如,跳过您可能计划在应用程序退出时进行的任何清理。