Ruby Enumerable and Array Extras: pluck and invoke for Ruby

The Prototype JavaScript Framework has almost all of the Array and Enumerable extensions that Ruby has, but the reverse doesn't seem to be true. One thing apparently missing from Ruby is pluck() (or invoke()). Picture the following scenario in Prototype JavaScript:

[1, 2, 3, 4].collect(function(n) { return n.toString() }) // collect() is the same as map()
// There's a better way to do it:
[1, 2, 3, 4].invoke('toString')
// => ['1', '2', '3', '4']

$$('div').collect(function(x) { return })
// The better way:
// => ['container', 'nav', 'header', 'content', 'main', 'footer']

In the previous case, you have an array of objects, and you want to invoke a particular method on all of the objects and have the returned data in a new array. In the latter, you have an array of DOM elements and you want to retrieve the id attribute of all of the elements and have the result in a new array.

In Ruby, since all class attributes are private and a method is required to retrieve an attribute from an object, pluck() does not apply, but at its core it is the same idea as invoke(), so we can safely say that in Ruby both pluck() and invoke() should do the same thing: take the results from calling a method on each object in an array and return them as a new array. Despite this, Ruby, as of version 1.8, does not provide this kind of method in the Enumerable module and inherently, Arrays, so you're missing out a syntactic sugar that Prototype JavaScripters are enjoying.

# Instead of doing this:
[1, 2, 3, 4].collect { |n| n.to_s } # => ["1", "2", "3", "4"]
# Wouldn't it be better to do this?
[1, 2, 3, 4].pluck :to_s
# Or this?
[1, 2, 3, 4].pluck "to_s"

Well, with these extras I wrote, now you can.

module Enumerable
  def pluck(method, *args)
    map { |x| x.send method, *args }
  alias invoke pluck

class Array
  def pluck!(method, *args)
    each_index { |x| self[x] = self[x].send method, *args }
  alias invoke! pluck!

As in Ruby, pluck!() is the destructive version of its counterpart; it alters the current array in place. As in Prototype, you can optionally specify the arguments, if any, to invoke the method with. invoke() and invoke!() are aliases of pluck() and pluck!(), respectively.

Hopefully, this can improve your Ruby Experience. This code is in public domain, do whatever you want with it. Whether you use it to save humanity, to take over the world, for the good of all of us, or to create Sharks with Freakin' Laser Beams™, I don't care. Although it would be nice if I get an honorable mention or something.