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/.