有啥作用!意味着在 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 savesave! 都修改了接收器(在某种意义上),但 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 方法定义的末尾? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

Ruby祖先链中的方法访问有啥问题

Ruby 中的方法和消息有啥区别? [关闭]

"||=" 在 Ruby 1.9.2 中有啥作用? [复制]

Ruby: :: 前缀有啥作用?

Ruby 中的独立问号有啥作用? [复制]

Ruby:没有块的选择/查找有啥用吗?