class EnumerableProxy < Object
  instance_methods.each { |meth| undef_method(meth) unless meth.to_s =~
/^__/ }

  def initialize(obj, meth, *args)
    @obj = obj
    @meth = meth
    @args = args
  end

  def method_missing(meth, *args, &block)
    @obj.send(@meth, *@args) { |item| item.send meth, *args, &block }
  end
end

class Array
  alias :__each__ :each
  def each(&blk)
    if blk
      __each__(&blk)
    else
      EnumerableProxy.new(self, :each)
    end
  end

  remove_method :collect
end

module Enumerable
  alias :__collect__ :collect
  def collect(&blk)
    if blk
      __collect__(&blk)
    else
      EnumerableProxy.new(self, :collect)
    end
  end
end

There, now you can do something like:

  ary = %w{a long list of words}
  lengths = ary.collect.length

Of course, Array#collect! still behaves as it used to. However, this
new #collect behaviour is defined in Enumerable so it will work in more
than just Array (although the #each stuff is on Array alone).