sawa
sawa

Reputation: 168209

What determines if a bang method on a mutable class returns `nil`?

Usually, bang methods on mutable a class such as String, Array, or Hash return nil when no modification is made. But some Array bang methods, i.e., collect!, map!, reverse!, rotate!, shuffle!, sort!, sort_by! and a Hash bang method, i.e., merge!, never return nil. What is the rationale behind this? What makes these methods different from others? I don't see why knowing whether an array was sorted by sort! is not useful while knowing whether an array was made unique by uniq! is useful.

Upvotes: 2

Views: 233

Answers (1)

Todd A. Jacobs
Todd A. Jacobs

Reputation: 84413

TL;DR

[B]ang methods on mutable class[es] return nil when no modification is made...[b]ut some Array bang methods...never return nil.

If there is an "official" rationale (along the lines of an official specification), I'm currently unaware of it. I personally suspect it's simply because some objects use nil as a return value to indicate errors (e.g. index out of range) rather than raising an exception, while others always return a valid object. I very much doubt there's an overriding philosophy there, although there appears to be a general consensus about when to use bang methods when you dig deep enough.

Bang Methods Aren't Inherently About Mutation

As one example, consider issue #5009, which requests:

[P]lease use bang methods (those that end with !) consistently in the API.

One useful response says:

[That bang is destructive] is a common misconception about the use of bang methods in Ruby. Bang does not indicate that a method mutates its receiver, merely that it should be used with caution.

Some Community Consensus on Bang Methods

There is definitely some consensus among Rubyists about when to use bang methods. The Ruby Style Guide currently offers the following guidelines:

  • The names of potentially dangerous methods...should end with an exclamation mark if there exists a safe version of that dangerous method.
  • Define the non-bang (safe) method in terms of the bang (dangerous) one if possible.

These guidelines seem consistent with the general idea that bang methods are about the caller being careful in choosing the method or handling the return value, rather than the bang acting as an indicator of what will be returned.

Upvotes: 2

Related Questions