2

I'm trying to learn Ruby by reading code, but I bumped into the following situation, which I cannot find in any of my tutorials/cheatsheets.

def foo!
    # do bar

    return bar  
  end

What is the point of "!" in a method definition?

4

3 回答 3

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 但不会引发异常)。

这是一个“抬头”!标志,但没有什么可以强制执行此操作。!如果您想迷惑和/或吓唬人们,您可以在 中结束您的所有方法。

于 2013-04-30T14:05:44.850 回答
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"

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

str = "hello"
p str.concat(" world") #=> "hello world"
p str #=> "hello world"
于 2013-04-30T14:01:07.157 回答
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" 
于 2013-04-30T14:06:03.043 回答