为什么在Ruby方法中使用感叹号?

Why are exclamation marks used in Ruby methods?

在Ruby中,有些方法有一个问号(?),它询问一个像include?这样的问题,询问是否包含所讨论的对象,然后返回一个真/假。

但是为什么有些方法有感叹号(!),而其他方法没有?

这是什么意思?


在方法,在通用,that the method指定的端!modify the对象将是我。红宝石在这些"危险方法",因为当他们改变了,会有人*参考。这是简单的字符串:for exampleP></

1
2
3
foo ="A STRING"  # a string called foo
foo.downcase!     # modifies foo itself
puts foo          # prints modified foo

这将输出:P></

1
a string

在标准的图书馆,there are a Lot of places of named similarly EEA对你一个方法,和一个没有!with the。are called the ones没有"安全的方法",和他们返回到原来的应用与copy of the changes to the copy with the unchanged,被叫方。这是!:without the example the sameP></

1
2
3
4
foo ="A STRING"    # a string called foo
bar = foo.downcase  # doesn't modify foo; returns a modified string
puts foo            # prints unchanged foo
puts bar            # prints newly created bar

这个输出:P></

1
2
A STRING
a string

这是我的心灵在一个会议,但很多后续of Ruby类的EN。它也helps You keep track of修饰什么要在你的代码。P></


the many things exclamation点均值,和有时不能告诉你很多"this is from other比它好危险,小心。"P></

当有人说,它的标准方法(method that often used to an object to变化本身的原因,but not总是。已知的多标准接收机的方法,相变和不安,他们有点exclamation(popshiftclear)和一些方法,以exclamation点不改变他们的接收器(exit!)。see this article for example。P></

其他differently图书馆可以使用它。在rails exclamation often the means that点安安法会把失败比失败的silently Rather在线数据库。P></

这是在多人使用它,但naming会议在subtly的不同方式。在你自己的代码的人使用它的拇指规则of is to a method is something当做"危险方法",especially when the same name与光子和one of them is exist"比其他的"危险"。虽然近事危险的‘的意思。P></


naming is from this lifted计划会议。P></

1.3.5 Naming conventions

By convention, the names of procedures
that always return a boolean value
usually end in ``?''. Such procedures
are called predicates.

By convention, the names of procedures
that store values into previously
allocated locations (see section 3.4)
usually end in ``!''. Such procedures
are called mutation procedures. By
convention, the value returned by a
mutation procedure is unspecified.


!that the method typically均值instead of the河畔的行为在结果对象回来。图书:from the Programming RubyP></

Methods that are"dangerous," or modify the receiver, might be named with a trailing"!".


它是最准确的方法与说,砰!一个或更多的是surprising version。there are many that没有爆炸这样的变化的方法和通用方法在.destroyas only have我在更安全的替代品的刘海exists in the核心库。P></

我们有一个在线阵列为实例,.compact!.compact和数组的方法,都改变了,但.compact!instead of归来…if there are自不nil' S在which is the阵列,自校正surprising比我更多。P></

唯一我不mutating method is found与爆炸Kernel.exit!which is s更多比你surprising .exit因为while the process is SystemExitcannot catch关闭。P></

rails和ActiveRecord的趋势继续,它uses爆炸这类的影响更多的是surprising for which raises在线.create!错误失败。P></


从themomorohoax.com:P></

在爆炸的方式可以used in the Order of below,在我个人的偏好。P></

1) An active record method raises an error if the method does not do
what it says it will.

2) An active record method saves the record or a method saves an
object (e.g. strip!)

3) A method does something"extra", like posts to someplace, or does
some action.

is the only使用在爆炸点:当你的思想about whether这是必要的,developers to save to the other of有annoyance为什么你是检查使用爆炸。P></

cues to the other developers两邦提供。P></

1) that it’s not necessary to save the object after calling the
method.

2) when you call the method, the db is going to be changed.

www.themomorohoax.com http:/ / / / / / * 11 2009年02 -使用-邦- exclamation rails的售后点方法P></


简单的解释:P></

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
foo ="BEST DAY EVER" #assign a string to variable foo.

=> foo.downcase #call method downcase, this is without any exclamation.

"best day ever"  #returns the result in downcase, but no change in value of foo.

=> foo #call the variable foo now.

"BEST DAY EVER" #variable is unchanged.

=> foo.downcase! #call destructive version.

=> foo #call the variable foo now.

"best day ever" #variable has been mutated in place.

但如果你在downcase!method called the above的讲解中,foodowncase permanently会改变。downcase!会返回字符串对象,但不是在字符串中的replace the changing the Place,footo downcase圆点。蓝晶石的*使用EN全downcase!除非是必要的。P></


称为"破坏性方法",它们倾向于更改所指对象的原始副本。

1
2
3
4
5
numbers=[1,0,10,5,8]
numbers.collect{|n| puts n*2} # would multiply each number by two
numbers #returns the same original copy
numbers.collect!{|n| puts n*2} # would multiply each number by two and destructs the original copy from the array
numbers   # returns [nil,nil,nil,nil,nil]

1
!

我喜欢把这看作是一个爆炸性的变化,它摧毁了之前发生的一切。bang或感叹号表示正在对代码进行永久保存的更改。

例如,如果使用Ruby的全局替换方法dcx1(3),则所做的替换是永久的。

另一种可以想象的方法是打开一个文本文件,执行查找和替换,然后保存。!在您的代码中也做同样的事情。

另一个有用的提醒是,如果你来自bash世界,那么sed -i也会产生类似的效果,即永久保存的改变。


底线:!方法只是更改被调用对象的值,而不带!的方法返回一个被操作的值,而不写入被调用方法的对象。

只有当您不打算需要在调用方法的变量中存储原始值时,才使用!

我更喜欢这样做:

1
2
3
foo ="word"
bar = foo.capitalize
puts bar

1
2
foo ="word"
puts foo.capitalize

而不是

1
2
3
foo ="word"
foo.capitalize!
puts foo

以防我再次访问原始值。