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