Further Enumerable::Proxy

Published September 25, 2009 in Ruby

My last post about Enumerable::Proxy ended with the possibility of being able to call .map.to_s, which appealed to me. I finally got around to making that possible.

I added the following to my definition of Enumerable::Proxy, which allows #each, #map, #select, #reject, and #all? to return an Enumerable::Proxy if no block is passed to them.

class Array
  %w(each map select reject all?).each do |method|
    aliased_target, punctuation = method.to_s.sub(/([?!])$/, ''), $1
    with_proxy = "#{aliased_target}_with_proxy#{punctuation}"
    without_proxy = with_proxy.sub "with", "without"

    class_eval %{
      def #{with_proxy}(&blk)
        blk.nil? ? proxy(:#{method}) : #{without_proxy}(&blk)
      end
      alias_method :#{without_proxy}, :#{method}
      alias_method :#{method}, :#{with_proxy}
    }
  end
end

The full definition is on github. Please fork and play.

Some examples:

some_records.each.update_attributes :name => 'fred'
%w(a b c d e).map.upcase #=> %w(A B C D E)
[1, 2, 3, 4, 5].map * 10 #=> [10, 20, 30, 40, 50]
[1, 2, 3, 4, 5].all? .respond_to? :to_f #=> true
[1, 2, 3].reject == 2 #=> [1, 3]
[1, 2, 3, 4, 5].select <= 3 #=> [1, 2, 3]

Update You can now install enumerable proxy with “sudo gem install enumerable-proxy” from gemcutter.