例如,array.pop
不需要爆炸来永久改变阵列。为什么会这样,在没有这种一致性的情况下开发这些某些Ruby方法背后的原因是什么?
答案 0 :(得分:12)
Bang方法最常用于区分同一方法的危险版本和安全版本。以下是一些人们可能希望与bang / no-bang组合区分开的示例:
然而,如果只有一个版本有意义,那么惯例就是让关闭。例如,pop
数组而不实际更改它是没有意义的。在这种情况下,它最终将成为一个不同的操作:Array#last
。许多方法都会更改它们所调用的对象,例如setter。我们也不需要用一声巨响来写这些,因为很明显他们会改变对象。
最后,有一些例外情况,一些开发人员可能会使用bang方法而不实现无需对手。在这些情况下,爆炸只是用来使方法调用在视觉上突出。例如:
答案 1 :(得分:2)
爆炸用于区分同一方法的危险版本和危险版本。只有一种pop
方法,因此无需区分。
注意:该方法的名称绝对没有任何关系。方法是否具有破坏性取决于它执行的代码,而不是它的名称。
答案 2 :(得分:1)
后缀!
表示方法是另一种方法的危险版本。例如,save!
是save
的危险版本。 Dangerous可能意味着编辑到位,执行更严格的错误等等。不需要在危险的方法上使用!
后缀,但不需要更安全的对应方法。此外,这只是一个命名约定,因此如果方法以!
结束或不以!
结束,Ruby不会限制您可以做什么和不能做什么。
有一种常见的误解,即编辑某些内容的每种方法都应以!
结尾。事实并非如此,只有在存在更危险版本的方法时才需要ActiveRecord::Base#save!
,这并不一定意味着危险方法已编辑到位。例如,在Rails中,ActiveRecord::Base#save
是执行验证的{{1}}版本。
答案 3 :(得分:1)
Ruby中bang的含义是“谨慎”。这意味着您应该谨慎使用该方法,仅此而已。我再也找不到参考,但有权威的人明确表示,砰是破坏性的方法。 Bang只是一个与谨慎相关的语义元素。程序员需要权衡一切并决定何时使用爆炸。
例如,在我的模拟gem中,我使用#step
方法来获取步长。
simulation.step #=> 0.42
和step!
方法实际执行模拟步骤。
simulation.step! #=> takes the simulation to the next time step
但至于#reset
方法,我认为“重置”这个词足够详细,并且没有必要使用bang来警告用户模拟状态将被破坏:
simulation.reset #=> resets the simulation back to the initial state
P.S。:现在我记得,曾经有一段时间,Matz半开玩笑说他后悔将方法引入Ruby中,因为bang在语义上是如此模糊。