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


Answers:


160

出于可读性考虑,它只是“糖衣”,但它们确实具有共同的含义:

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

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


22
一个重要的注意事项是,如果还具有相应的非爆炸方法,则仅应使用爆炸方法。爆炸用于将方法的“更令人惊讶”版本与“更不令人惊讶”版本区分开。如果只有一种方法,则无需区别对待,也不要用爆炸来命名。Array#clear例如,参见。清除数组。清除数组自然会使它变异。对此没有什么奇怪的,因此名称已经很清楚了:因此,请放心。参见ruby-forum.com/topic/176830#773946
约尔格W¯¯米塔格

2
根据Ruby样式指南,在@JörgWMittag中添加:潜在危险方法的名称(即,修改self或参数的方法的名称,exit!(不像exit那样运行终结器)等)感叹号,如果存在该危险方法的安全版本
Tod Birdsall 2015年

2
当心,并非总是如此。例如,Ruby Array#concat docs.ruby-lang.org/en/2.0.0/Array.html#method-i-concat。您可能会被严重烧毁的地方是MyActiveRecordModel.column_names.concat(...)。相反,您必须先克隆它,然后再进行连接。
wintondeshong


8

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


5

与我所认为的大多数编程语言相反...

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

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

按照惯例,潜在的“危险”方法(即,修改自我或自变量,退出!等的方法)以感叹号结尾。

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


1
以结尾的方法?也称为谓词方法。
Waseem

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”列并抛出异常。

相反,您必须先克隆它,然后再进行连接。幸运的是我的测试套件抓住了这个,但是..

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.