Hi -- On Sun, 2 Dec 2007, MonkeeSage wrote: > On Dec 1, 1:13 pm, "David A. Black" <dbl... / rubypal.com> wrote: >> Hi -- >> >> >> >> On Sun, 2 Dec 2007, Pat Maddox wrote: >>> On Dec 1, 2007 10:55 AM, samppi <rbysam... / gmail.com> wrote: >>>> As a novice in Ruby, I love its elegance and consistence; it's now one >>>> of my favorite languages. One of my favorite features is the practice >>>> of ending the names of mutating methods with an exclamation point to >>>> distinguish them from similar accessor methods, like "reverse" vs. >>>> "reverse!" >> >>>> I'm curious, though, about an apparent inconsistency with this rule in >>>> Array: push, pop, shift, and unshift. All four methods modify objects >>>> in-place, yet they don't have an "!". Why is this? >> >>>> The only reason I can think of is that they lack "!"s in other >>>> languages, which is a pretty tenuous reason at best--not many >>>> languages name their methods "empty?" or "map!" instead of "is_empty" >>>> or "map"...and in any case, Ruby is different enough in syntax and >>>> style that it shouldn't even matter. >> >>> ! doesn't signify a mutating method, it signifies a destructive >>> version of a method. Per your example, #reverse revers the array >>> without changing it, whereas #reverse! is destructive. #push and #pop >>> do not have a nondestructive version. >> >> For more along the same lines, see:http://dablog.rubypal.com/2007/8/15/bang-methods-or-danger-will-rubyist >> >> David >> >> -- >> Upcoming training by David A. Black/Ruby Power and Light, LLC: >> * Intro to Rails, London, UK, December 3-6 (by Skills Matter) >> Seehttp://www.rubypal.comfor details and 2008 announcements! > > "Dangerous" seems kind of ambiguous. Does it mean that the code does > something other than I expect? Or, that it will break code relying on > the non-bang version? Or some combination? Or something else entirely? It varies. Just think of it as a "heads up". It means that you need to make sure you really know what the method does. A classic example is: "abc".gsub!(/x/, "z") which returns nil, because no substitutions have occurred. The ! warns you that you really need to know what's going on -- in this case, both that the receiver will be changed if there are substitutions, and that the return value is different from that of the non-! version when there aren't. > E.g., people coming from Haskell / Clean would likely say that *any* > mutation of the receiver is "dangerous", and label everything that > doesn't operate on a copy with a "!" > > a = [1,2] > b = a > def impure!(a) > a.replace([1,2,3]) > end > impure!(a) # dangerous! > b # => [1, 2, 3] Well, people coming from Ruby wouldn't do that :-) The thing to remember is that ! methods always exist (or should always exist) in a pair with non-! counterparts. The ! is not just an exclamation of surprise; it's supposed to mean something *in relation to* its context. David -- Upcoming training by David A. Black/Ruby Power and Light, LLC: * Intro to Rails, London, UK, December 3-6 (by Skills Matter) See http://www.rubypal.com for details and 2008 announcements!