有啥作用!意味着在 Ruby 方法定义的末尾? [复制]
Posted
技术标签:
【中文标题】有啥作用!意味着在 Ruby 方法定义的末尾? [复制]【英文标题】:What does ! mean at the end of a Ruby method definition? [duplicate]有什么作用!意味着在 Ruby 方法定义的末尾? [复制] 【发布时间】:2013-04-24 11:38:52 【问题描述】:我正在尝试通过阅读代码来学习 Ruby,但我遇到了以下情况,在我的任何教程/备忘单中都找不到。
def foo!
# do bar
return bar
end
“!”的意义何在?在方法定义中?
【问题讨论】:
Ruby 方法定义体开头的//
是什么意思?
【参考方案1】:
!
是一个“bang”方法,它改变了接收者,是 Ruby 中的一个约定。
您可以定义一个!
版本,它可能像非爆炸方法一样工作,但如果其他程序员不查看您的方法定义,就会误导他们。
当接收者没有改变时,bang 方法又返回nil
。
没有!
的例子——你可以看到源字符串没有改变:
str = "hello"
p str.delete("l") #=> "heo"
p str #=> "hello"
!
的示例 - 您可以看到源字符串已更改:
str = "hello"
p str.delete!("l") #=> "heo"
p str #=> "heo"
注意:有一些非 bang 版本的方法,也可以改变接收者对象:
str = "hello"
p str.concat(" world") #=> "hello world"
p str #=> "hello world"
【讨论】:
谢谢,这是有道理的,所以这只是一个 ruby 约定:D 刘海本身不使用。当有非爆炸替代品时使用它。 dablog.rubypal.com/2007/8/15/… @thomthom 我知道,我有没有提到任何错误?指点我那里,我会纠正的。 这个答案具有误导性。!
表示该方法是另一种方法的潜在危险版本。很多时候,!
确实修改了接收器(这是危险的),但其他时候会发生其他影响。例如,在 Rails 中,ActiveRecord save
和 save!
都修改了接收器(在某种意义上),但 save!
方法可能会引发异常。吉姆·斯图尔特的答案是正确的答案。
@LeviStanley 我不知道您告诉我的回答在何种意义上具有误导性。但想告诉你,如果无法更改,bang 方法会返回nil
。这个问题被标记为Ruby
。所以根据 ruby,我写的 bang 方法就是这样。【参考方案2】:
Ruby 不会将!
视为方法名称末尾的特殊字符。按照惯例,以!
结尾的方法具有某种副作用或方法作者试图引起注意的其他问题。示例是执行就地更改、可能引发异常或不顾警告继续执行操作的方法。
例如,String#upcase!
与 String#upcase
的比较如下:
1.9.3p392 :004 > foo = "whatever"
=> "whatever"
1.9.3p392 :005 > foo.upcase
=> "WHATEVER"
1.9.3p392 :006 > foo
=> "whatever"
1.9.3p392 :007 > foo.upcase!
=> "WHATEVER"
1.9.3p392 :008 > foo
=> "WHATEVER"
ActiveRecord 将 bang 方法广泛用于 save!
之类的事情,它会在失败时引发异常(与 save
相比,它返回 true/false 但不会引发异常)。
这是一个“抬头!”标志,但没有什么可以强制执行此操作。如果您想迷惑和/或吓唬人们,您可以在 !
中结束您的所有方法。
【讨论】:
可能需要补充一点,!
方法往往具有不同的返回值(最明显的是 nil
,当没有任何变化时)这可能会导致意外和微妙的错误。【参考方案3】:
!
不是方法定义,而是声明方法时使用的约定,此方法将更改对象。
1.9.3-p194 :004 > a="hello "
=> "hello "
1.9.3-p194 :005 > a.strip
=> "hello"
1.9.3-p194 :006 > a
=> "hello "
1.9.3-p194 :007 > a.strip!
=> "hello"
1.9.3-p194 :008 > a
=> "hello"
【讨论】:
以上是关于有啥作用!意味着在 Ruby 方法定义的末尾? [复制]的主要内容,如果未能解决你的问题,请参考以下文章