From: Kai Kai Date: 2008-12-09T01:28:49+09:00 Subject: Re: filtering blocks Hm, I think the problem is not to filter a block (that's also possible, because in ruby blocks are also objects of the class Proc). You want to filter an Enumeration. Therefore you could use the class Enumerator. require "enumerator" class Integer def odds() if block_given? then 1.upto(self) do |number| yield number if number % 2 == 1 end else Enumerable::Enumerator.new(self, :odds) end end def evens() if block_given? then 1.upto(self) do |number| yield number if number % 2 == 0 end else Enumerable::Enumerator.new(self, :even) end end end 5.odds.each do |number| puts number end # => 1, 3, 5 5.odds.any? do |number| number % 3 == 0 end # => true And of course you can add more "filters" by extending the Enumerator class, or better, a subclass of Enumerator which handles only with Integers. require "enumerator" class Integer def odds() if block_given? then 1.upto(self) do |number| yield number if number % 2 == 1 end else Enumerable::Enumerator::Integer.new(self, :odds) end end def evens() if block_given? then 1.upto(self) do |number| yield number if number % 2 == 0 end else Enumerable::Enumerator::Integer.new(self, :even) end end end module Enumerable class Enumerator class Integer < Enumerator def prime if block_given? then each do |number| # primitive prime algorithm yield(number) unless (2..Math.sqrt(number)).any? do |i| number % i == 0 end end else Enumerable::Enumerator.new(self, :prime) end end def odds if block_given? then each do |number| yield number if number % 2 == 1 end else Enumerable::Enumerator.new(self, :odds) end end def evens if block_given? then each do |number| yield number if number % 2 == 0 end else Enumerable::Enumerator.new(self, :evens) end end end end end 12.odds.prime.each {|x| p x} -- Posted via http://www.ruby-forum.com/.