tags:

views:

1420

answers:

4

In Ruby some methods have a question mark (?) that ask a question like "include?" that ask if the object in question is included, this then returns a true/false.

But why do some methods have exclamation marks (!) where others don't?

What does it mean?

+24  A: 

In general, methods that end in ! indicate that the method will modify the object it's called on. Ruby calls these "dangerous methods" because they change state that someone else might have a reference to. Here's a simple example for strings:

foo = "A STRING"  # a string called foo
foo.downcase!     # modifies foo itself
puts foo          # prints modified foo

This will output:

a string

In the standard libraries, there are a lot of places you'll see pairs of similarly named methods, one with the ! and one without. The ones without are called "safe methods", and they return a copy of the orignal with changes applied to the copy, with the callee unchanged. Here's the same example without the !:

foo = "A STRING"    # a string called foo
bar = foo.downcase  # doesn't modify foo; returns a modified string
puts foo            # prints unchanged foo
puts bar            # prints newly created bar

This outputs:

A STRING
a string

Keep in mind this is just a convention, but a lot of ruby classes follow it. It also helps you keep track of what's getting modified in your code.

tgamblin
Is this just a naming convention or does it actually do something?
metanaito
It's just a naming convention, but most of the ruby classes follow it.
tgamblin
There's also cases like exit versus exit! and (in rails) save versus save!
Andrew Grimm
Be very careful - many smaller libraries don't follow this convention. If strange things are happening, often replacing obj.whatever! with obj=obj.whatever! fixes it. Very frustrating.
Sarah Mei
good advice -- I'm not sure how consistently library implementors use this!
tgamblin
+3  A: 

! typically means that the method acts upon the object instead of returning a result. From the book Programming Ruby:

Methods that are dangerous,'' or modify the receiver, might be named with a trailing !''

Pesto
+5  A: 

This naming convention is lifted from Scheme.

1.3.5 Naming conventions

By convention, the names of procedures that always return a boolean value usually end in ``?''. Such procedures are called predicates.

By convention, the names of procedures that store values into previously allocated locations (see section 3.4) usually end in ``!''. Such procedures are called mutation procedures. By convention, the value returned by a mutation procedure is unspecified.

Steven Huwig
+6  A: 

The exclamation point means many things, and sometimes you can't tell a lot from it other than "this is dangerous, be careful".

As others have said, in standard methods it's often used to indicate a method that causes an object to mutate itself, but not always. Note that many standard methods change their receiver and don't have an exclamation point (pop, shift, clear), and some methods with exclamation points don't change their receiver (exit!). See this article for example.

Other libraries may use it differently. In Rails an exclamation point often means that the method will throw an exception on failure rather than failing silently.

It's a naming convention but many people use it in subtly different ways. In your own code a good rule of thumbs is to use it whenever a method is doing something "dangerous", especially when two methods with the same name exist and one of them is more "dangerous" than the other. "Dangerous" can mean nearly anything though.

Brian Carper