
-----------------------------------
wtd
Tue Jul 03, 2007 6:21 pm

The magical each_* solution!
-----------------------------------
class Object
    def method_missing(msg, *args)
        if (msg.to_s =~ /^each_([a-z][a-z\d_]*)$/i and method_name = $1.to_sym) and ((respond_to? method_name and begin (c = send method_name, *args).respond_to? :each rescue false end) or (respond_to? :"#{method_name}s" and begin (c = send :"#{method_name}s", *args).respond_to? :each rescue false end))
            c.each { |x| yield x }
        else
            super
        end        
    end
end

$ irb --prompt simple
>> class Foo
>>     def bar
>>         [1, 2, 3]
>>     end
>> end
=> nil
>> Foo.new.each_bar { |x| puts x }
1
2
3
=> [1, 2, 3]
>>

-----------------------------------
wtd
Wed Jul 04, 2007 12:31 am

Re: The magical each_* solution!
-----------------------------------
This code appears not to work, and I have very little idea why not.  Anyone want to take a crack at it?

class Object
    def method_missing(msg, *args)
        msg.to_s =~ /^each_([a-z][a-z\d_]*)$/i and method_name = $1.to_sym and c = (respond_to_and_enumerable(method_name, *args) or respond_to_and_enumerable(:"#{method_name}s", *args)) ? c.each { |x| yield x } : super
    end

    def respond_to_and_enumerable(msg, *args)
        (result = send msg, *args).respond_to? :each and result
    rescue ArgumentError
        false
    end
end

-----------------------------------
wtd
Wed Jul 04, 2007 12:49 am

RE:The magical each_* solution!
-----------------------------------
Fixed!

class Object
    def method_missing(msg, *args)
        (msg.to_s =~ /^each_([a-z][a-z\d_]*)$/i and method_name = $1.to_sym and c = (respond_to_and_enumerable method_name, *args or respond_to_and_enumerable :"#{method_name}s", *args)) ? c.each { |x| yield x } : super
    end

    def respond_to_and_enumerable(msg, *args)
        (result = send msg, *args).respond_to? :each and result
    rescue ArgumentError
        false
    end
end

-----------------------------------
wtd
Wed Jul 04, 2007 12:52 am

RE:The magical each_* solution!
-----------------------------------
And one more slightly different version:

class Object
    def method_missing(msg, *args)
        msg.to_s =~ /^each_([a-z][a-z\d_]*)$/i and method_name = $1.to_sym and c = (respond_to_and_enumerable method_name, *args or respond_to_and_enumerable :"#{method_name}s", *args) and c.each { |x| yield x } or super
    end

    def respond_to_and_enumerable(msg, *args)
        (result = send msg, *args).respond_to? :each and result
    rescue ArgumentError
        false
    end
end

-----------------------------------
Cervantes
Wed Jul 04, 2007 10:07 am

RE:The magical each_* solution!
-----------------------------------
Nice, wtd. I do so love method_missing. I was thinking of something similar, well, about a year ago. I should really try to implement it.
