关于ruby:方法名称末尾的“!”和“?”的目的是什么?

What is the purpose of “!” and “?” at the end of method names?

有时我看到Ruby中有"?"的方法。还有"!"最后,例如:

1
2
3
4
name ="sample_string"
name.reverse
name.reverse!
name.is_binary_data?

我想知道他们的目的是什么?它们只是语法糖衣吗?


这是"只是糖衣"的可读性,但他们有共同的含义:

  • !结尾的方法执行一些永久或潜在危险的更改;例如:
    • Enumerable#sort返回对象的已排序版本,而Enumerable#sort!将其排序到位。
    • 在rails中,如果保存失败,ActiveRecord::Base#save将返回false,而ActiveRecord::Base#save!将引发异常。
    • Kernel::exit导致脚本退出,而Kernel::exit!则立即退出,绕过任何退出处理程序。
  • ?结尾的方法返回一个布尔值,这使得代码流更直观地像一个句子-if number.zero?读起来像"如果数字为零",但if number.zero看起来很奇怪。

在您的示例中,name.reverse的计算结果为反转字符串,但只有在name.reverse!行之后,name变量才实际包含反转名称。name.is_binary_data?看起来像是"name二进制数据吗?".


问号表示该方法返回布尔值。已在此处回答:

问号运算符在Ruby中是什么意思?

bang表示该方法作用于对象本身。已在此处回答:

为什么在Ruby方法中使用感叹号?


在Ruby中,?意味着该方法将返回一个布尔值,并且!修改它被调用的对象。它们是为了提高代码的可读性。


我想,与大多数编程语言相比…

Ruby, methods are allowed to end with question marks or exclamation marks.

By convention, methods that answer questions (i.e. Array#empty? returns true if the receiver is empty) end in question marks.

Potentially"dangerous" methods (ie methods that modify self or the arguments, exit! etc.) by convention end with exclamation marks.

来自:http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/,有趣的方法名称部分


当心,情况并非总是如此。例如,ruby array concat http://docs.ruby-lang.org/en/2.0.0/array.html method-i-concat。

你会被严重烧伤的地方是像MyActiveRecordModel.column_names.concat([url])这样的东西。稍后,与MyActiveRecordModel相关的调用将尝试查找MyActiveRecordModel的"url"列并引发。

相反,您必须在执行concat之前克隆它。幸运的是,我的测试套件捕获了这个,但是……抬起头来!