我正在尝试通过阅读代码来学习Ruby,但我遇到了以下情况,我在任何教程/备忘单中都找不到。
def foo!
# do bar
return bar
end
“!”有什么意义?在方法定义中?
答案 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"