Теодор обнови решението на 27.10.2014 00:38 (преди около 11 години)
+class NumberSet < Array
+  def <<(number)
+    self.insert(-1, number) if not self.include? number
+  end
+
+  def [](filter)
+    NumberSet.new self.select {|number| filter.call number}
+  end
+end
+
+module FilterOperators
+  def &(filter)
+    Proc.new {|number| self.call(number) && filter.call(number)}
+  end
+
+  def |(filter)
+    Proc.new {|number| self.call(number) || filter.call(number)}
+  end
+end
+
+class Proc
+  include FilterOperators
+end
+
+class Filter
+  include FilterOperators
+  def initialize(&block)
+    @block = block
+  end
+
+  def call(number)
+    @block.call number
+  end
+end
+
+class TypeFilter
+  include FilterOperators
+  def initialize(number_type)
+    case number_type
+      when :integer then @number_type = [Integer]
+      when :real    then @number_type = [Float, Rational]
+      when :complex then @number_type = [Complex]
+    end
+  end
+
+  def call(number)
+    @number_type.any? {|type| number.is_a? type}
+  end
+end
+
+class SignFilter
+  include FilterOperators
+  def initialize(sign_type)
+    case sign_type
+      when :positive      then @sign_type = ">0"
+      when :non_negative  then @sign_type = ">=0"
+      when :negative      then @sign_type = "<0"
+      when :non_positive  then @sign_type = "<=0"
+    end
+    @sign_type
+  end
+
+  def call(number)
+    eval(number.to_s + @sign_type)
+  end
+end
- Не използвай 
self, излишно е в повечето случай, викай директно инстанционните методи. - 
evalIS EVIL. Определено е спомогнал с краткоста на решението, но го промени, тъкмо ще се отървеш и от@sign_type. - Monkey patching-а на 
Procсъщо не е добра идея, ако не мислиш като цяло да разширяваш функционалноста на пачваният клас, не го прави. В твоя случей го разширяваш да работи с конкретни класове и е далеч от generic. 
