有时我看到Ruby中的方法有“?”和“!”在他们的最后,例如:
name = "sample_string"
name.reverse
name.reverse!
name.is_binary_data?
我想知道他们的目的是什么?它们只是语法糖衣吗?
答案 0 :(得分:149)
为了便于阅读,它只是“糖衣”,但它们确实有共同的含义:
!
结尾的方法执行某些永久性或潜在危险的更改;例如:
Enumerable#sort
会返回对象的排序版本,而Enumerable#sort!
会对其进行排序。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)
答案 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之前克隆它。幸运的是我的测试套件抓住了这个,但是......抬起头来!