106

有时我会在 Ruby 中看到带有“?”的方法。和 ”!” 在他们的最后,例如:

name = "sample_string"
name.reverse
name.reverse!
name.is_binary_data?

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

4

5 回答 5

167

为了可读性,它“只是糖衣”,但它们确实具有共同的含义:

  • !以执行某些永久性或潜在危险更改结尾的方法;例如:
    • Enumerable#sort返回对象的排序版本,同时Enumerable#sort!对其进行排序。
    • 在 Rails 中,ActiveRecord::Base#save如果保存失败则返回 false,同时ActiveRecord::Base#save!引发异常。
    • Kernel::exit导致脚本退出,同时Kernel::exit!立即退出,绕过任何退出处理程序。
  • 方法以?返回一个 boolean结尾,这使得代码的流动更加直观,就像一个句子——if number.zero?读起来像“如果数字为零”,但if number.zero看起来很奇怪。

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

于 2011-08-24T16:34:05.920 回答
19

问号表示该方法返回布尔值。已经在这里回答了:

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

bang 表示该方法作用于对象本身。已经在这里回答了:

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

于 2011-08-24T16:33:34.297 回答
10

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

于 2011-08-24T16:34:13.753 回答
6

与 - 我想 - 大多数编程语言相比......

Ruby,方法允许以问号或感叹号结尾。

按照惯例,回答问题的方法(即 Array#empty? 如果接收者为空则返回 true)以问号结尾。

按照惯例,潜在的“危险”方法(即修改 self 或参数、exit!等的方法)以感叹号结尾。

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

于 2011-08-24T16:35:12.487 回答
1

请注意,情况并非总是如此。以 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 之前克隆它。幸运的是我的测试套件抓住了这个,但是..抬头!

于 2016-08-26T14:02:37.197 回答