什么意味着在Ruby方法定义的最后?

时间:2013-04-30 13:59:25

标签: ruby

我正在尝试通过阅读代码来学习Ruby,但我遇到了以下情况,我在任何教程/备忘单中都找不到。

def foo!
    # do bar

    return bar  
  end

“!”有什么意义?在方法定义中?

3 个答案:

答案 0 :(得分:11)

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-methods来处理像save!这样的事情,它会在失败时引发异常(vs save,返回true / false但不引发异常)。

这是一个“抬头!”旗帜,但没有任何强制执行此操作。如果您想混淆和/或吓唬人,可以在!中结束所有方法。

答案 1 :(得分:1)

!是一个“爆炸”方法,它改变了接收器并且是Ruby中的惯例。

您可以定义!版本,它可能像非爆炸方法一样工作,但如果他们没有查看您的方法定义,那么它会误导其他程序员。

当没有对接收者进行任何更改时,

bang方法依次返回nil

没有!的示例 - 您可以看到源字符串尚未更改:

str = "hello"
p str.delete("l") #=> "heo"
p str #=> "hello"

!的示例 - 您可以看到源字符串已更改:

str = "hello"
p str.delete!("l") #=> "heo"
p str #=> "heo"

注意:有一些非爆炸版本方法,也可以更改接收器对象:

str = "hello"
p str.concat(" world") #=> "hello world"
p str #=> "hello world"

答案 2 :(得分:0)

!不是方法定义,而是在声明方法时使用的约定,此方法更改对象。

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"