From: James Gray Date: 2008-05-06T21:58:17+09:00 Subject: Re: delegation question, where I want prototype style delegation On May 6, 2008, at 1:00 AM, Sam Roberts wrote: > I want to make an object that behaves like another object would, if > that > object had had it's #each method redefined. What you really want in this case is normal inheritance, so the overridden each() method replaces the original. Then the only thick becomes getting the existing object into an equivalent subclass form. We can use a little Ruby magic to track subclasses and do the conversion for us: class Base def self.subclasses @subclasses ||= [ ] end def self.inherited(subclass) subclasses << subclass end def self.subclass(snake_case_name) camel_case_name = snake_case_name.gsub(/(?:\A|_)(.)/) { $1.capitalize } subclasses.find { |sc| sc.to_s == camel_case_name } end include Enumerable def initialize(ary) @ary = Array(ary) end def each(&block) @ary.each(&block) end def show "show: #{to_a.join(", ")}" end def method_missing(method, *args, &block) if method.to_s =~ /\Aas_(\w+)\z/ and (sc = self.class.subclass($1)) sc.new(@ary) else super end end end class Negated < Base def each super { |e| yield -e } end end class Plus10 < Base def each super { |e| yield e + 10 } end end puts "Base:" b = Base.new(1..3) puts b.show puts "Negated:" puts b.as_negated.show puts "Plus 10:" puts b.as_plus_10.show __END__ Hope that helps. James Edward Gray II