"!"的目的是什么?和"?" 在方法名称的末尾?

its*_*ode 96 ruby syntax

有时我看到Ruby中的方法有"?" 和"!" 在他们的最后,例如:

name = "sample_string"
name.reverse
name.reverse!
name.is_binary_data?
Run Code Online (Sandbox Code Playgroud)

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

jtb*_*des 153

它只是"糖衣"以提高可读性,但它们确实有共同的含义:

  • 最终!执行某些永久或潜在危险变化的方法 ; 例如:
    • 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二进制数据?".

  • 一个重要的注意事项是,如果你也有一个相应的非爆炸方法,你应该只有一个爆炸方法.爆炸用于区分方法的"更令人惊讶"的版本与"不太令人惊讶"的版本.如果你只有一种方法,那么就没有必要进行区分,你不应该用它来命名.例如,参见`Array#clear`.它清除阵列.清除阵列会自然地改变它.没有什么可以令人惊讶的,这个名字已经清楚了,因此:没有爆炸.请参阅https://www.ruby-forum.com/topic/176830#773946. (19认同)
  • 根据 [Ruby 风格指南](https://github.com/bbatsov/ruby-style-guide#dangerous-method-bang),添加@JörgWMittag 所说的:潜在危险方法的名称(即修改self 或参数,exit!(不像 exit 那样运行终结器)等)应该以感叹号结尾 **如果存在该危险方法的安全版本**。 (2认同)
  • 请注意,情况并非总是如此。例如,Ruby Array#concat http://docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat。您可能会被严重烧毁的地方是 MyActiveRecordModel.column_names.concat(...) 之类的东西。相反,您必须在执行 concat 之前克隆它。 (2认同)

Bil*_*ill 14

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

问号运算符在Ruby中意味着什么?

爆炸表明该方法作用于对象本身.已在这里回答:

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


J L*_*erg 7

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


mik*_*iku 5

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

Ruby,方法允许以问号或感叹号结束.

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

按惯例,潜在的"危险"方法(即修改自我或参数的方法,退出!等)以感叹号结束.

来源:http://www.ruby-lang.org/en/documentation/ruby-from-other-languages/,节搞怪方法名

  • 以“?”结尾的方法也称为谓词方法。 (2认同)