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

时间:2011-08-24 16:30:59

标签: ruby syntax

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

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

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

5 个答案:

答案 0 :(得分:149)

为了便于阅读,它只是“糖衣”,但它们确实有共同的含义:

  • !结尾的方法执行某些永久性或潜在危险的更改;例如:
    • 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二进制数据?”。

答案 1 :(得分:13)

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

What does the question mark operator mean in Ruby?

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

Why are exclamation marks used in Ruby methods?

答案 2 :(得分:7)

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

答案 3 :(得分:5)

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

  

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

     

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

     

潜在的“危险”方法(即修改self或参数的方法,退出!等)按约定以感叹号结束。

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

答案 4 :(得分:0)

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