Computer Science Canada

The magical each_* solution!

Author:  wtd [ Tue Jul 03, 2007 6:21 pm ]
Post subject:  The magical each_* solution!

code:
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


code:
$ 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]
>>

Author:  wtd [ Wed Jul 04, 2007 12:31 am ]
Post subject:  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?

code:
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

Author:  wtd [ Wed Jul 04, 2007 12:49 am ]
Post subject:  RE:The magical each_* solution!

Fixed!

code:
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

Author:  wtd [ Wed Jul 04, 2007 12:52 am ]
Post subject:  RE:The magical each_* solution!

And one more slightly different version:

code:
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

Author:  Cervantes [ Wed Jul 04, 2007 10:07 am ]
Post subject:  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.


: