Mining ActiveSupport: Object#returning

Posted by Jamis on October 27, 2006 @ 08:16 AM

ActiveSupport is the unsung hero of Rails. Much of what makes Rails code beautiful and powerful is implemented in ActiveSupport. It adds numerous methods to many of the core classes, which are used throughout Rails. If you don’t mind digging around, you can find all kinds of handy tricks to use in your own applications.

Consider this common idiom:

1
2
3
4
5
6
7
def create_book
  book = Book.new
  book.title = "Trafalgar: The Nelson Touch"
  book.author = "David Howarth"
  @db.add(book)
  book
end

You create an object, set some properties on it, and then return the object. ActiveSupport adds a new method (called returning) to Object, which can be used to beautify (and in some cases, simplify) that idiom:

1
2
3
4
5
6
7
def create_book
  returning Book.new do |book|
    book.title = "Trafalgar: The Nelson Touch"
    book.author = "David Howarth"
    @db.add(book)
  end
end

The latter is no shorter than the former, but it reads more elegantly. It feels more “Rubyish”. And there are times that it can save you a few lines of code, if that’s important. (Just scan the Rails source code for more examples.)

Object#returning has been in Rails for quite some time, being checked in on March 20, 2005 in revision 949. (It now lives in active_support/core_ext/object/misc.rb, and behaves slightly differently than the original did, but it is still as brief as ever.)

Looking at the comment for that method, you’ll see it described as “A Ruby-ized realization of the K combinator, courtesy of Mikael Brockman.”

In researching this article, I googled (pardon me, “searched Google”) for Mikael Brockman, to see just who this genius is. Unfortunately, though he seemed active enough in 2005, he appears to have fallen off the face of the Internet since then. At any rate: big props to Mr. Brockman for contributing this.

If you’re into functional programming at all, you probably know right away what the K combinator is. For the rest of us, this article is helpful (if a bit on the academic side, but that’s about par for the course for most reading about functional topics). Basically, the K combinator is a function of two arguments, that merely returns the first argument. The second argument is useful only for the side-effects it has on the first argument. The implementation of this in Ruby is beautifully succinct:

1
2
3
4
def returning(value)
  yield(value)
  value
end

It takes a value (the first argument), yields it to the associated block (the implicit second argument), and then returns the value. The block is used to operate on the first argument, and thus (by its side-effects) provides the actual work of this method.

It’s pretty handy!

Posted in Spotlight

Comments

Have something to add? Click here to leave a comment.

27 Oct 2006

1. Mischa said...

Nice tip! Thanks.

2. Doug Bryant said...

In terms of this example, is the “returning” method really necessary? Wouldn’t the Book.new call leave the last object on the stack and thus get returned by the method? Or does the @db.add(book) mess this up somehow? Did I miss something?

3. Jamis said...

Doug, note that Object#returning is never “necessary”. It really more of an esthetic improvement, syntactic sugar.

However, if you know that @db.add(book) will return book, you could just leave it as the last statement in the method and you’d be fine. You won’t always have that luxury, though, especially if you are dealing with code that you didn’t write, and which you don’t particularly care to monkeypatch.

4. Garth said...

I’ve been looking for an explaination of this for some time now – I never knew it was part of Rails until now. Cheers!

5. Joe Van Dyk said...

I’m still not sure if I’ll use it much in my code. It doesn’t save any typing, and I don’t think it simplifies everything (in fact, it makes future readers of your code be familiar with another function).

6. Brian Buckley said...

A slight twist on this k combinator concept is when the first argument is “self”. Surprisingly useful.

class Object def tap yield self self end end

from http://moonbase.rydia.net/mental/blog/programming/eavesdropping-on-expressions.html

28 Oct 2006

7. Steve Shreeve said...

Thanks Jamis for this simple but wonderful tip! Seeing Brian’s last post, I made a handy “with” method, that combines both the “returning” and “tap” methods mentioned above into one. A nice little bit of syntactical sugar.

class Object def with(obj=self) yield(obj) obj end end

8. Gerry said...

IMO a simple ‘return book’ would make the code clearer and simplier. Maybe not more rubyish but I bet more people will understand it right away then the fancy example.

I never could understand why it’s considered good ruby style to not use the ‘return’ keyword. In some places it makes the code ugly but in others it makes it more readable.

29 Oct 2006

9. Jim said...

Wow, ask a question and get a whole post for a response. Thank you for taking the time to write this up Jamis, you do an excellent job of explaining the inner workings of Rails.