Enumerable::Proxy
Published September 23, 2009
in Ruby
I’ve been playing with a pattern that replaces the Rails Symbol#to_proc pattern. Instead of doing
@my_objects.each(&:save!)
You would do
@my_objects.proxy(:each).save!
The advantage to this pattern is that it also allows passing in arguments to the proxied method, as in
%w(a b c).proxy(:all?).respond_to? :downcase #=> true [1, 2, 3].proxy(:map) * 10 #=> [10, 20, 30]
I’ve been using this pattern and am quite happy with it, so I thought I’d publish it. Here’s the monkeypatch:
module Enumerable def proxy(method) Proxy.new method, self end class Proxy instance_methods.each { |m| undef_method m unless m =~ /^__/ } def initialize(method, enumerable) @method, @enumerable = method, enumerable end def method_missing(method, *args) @enumerable.send(@method) {|a| a.send method, *args} end end end
I’d love feedback on the interface. Is there a shorter, but still clear replacement for “proxy”? Would it totally flip people out if #each and #map returned an Enumerable::Proxy if called with no arguments? That would let you do %w(a b c).each.to_s, which looks pretty cool.
Edit: I implemented the above suggestion. More details are here