On Dec 1, 4:13 pm, MonkeeSage <MonkeeS... / gmail.com> 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.comfordetails 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? > > 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] > > Regards, > Jordan In thinking about it a little bit and looking at the stdlib, I think it is accurate to say that !-methods have one of these characteristics: 1.) Modifies receiver in-place (e.g., String#succ!). 2.) Causes some side-effect that is incompatible or sufficiently different from the non-bang version (e.g., Thread#kill!) -- i.e., is "dangerous". 3.) Implies both 1 & 2 (e.g., String#gsub!). So in regard to the question posed by the OP, it seems that yes, to be perfectly consistent with the usual syntax, pop, push and un/shift should be suffixed with a bang. However, like John said, sometimes it just makes sense to break the syntax. And this is a perfect example; those methods don't have any semantic meaning that does not fall under the above characterization of !-methods (i.e., there would be no "normal" version, just a bang version), and their names are perfectly descriptive. Further, given the second characterization, people may think they are somehow unusual from they way they work in other languages (or just their "intuitive" sense). So there is really no benefit to having them as !-methods. Regards, Jordan