Ангел обнови решението на 23.10.2014 00:34 (преди около 11 години)
+class NumberSet
+  include Enumerable
+
+  def initialize()
+    @set = []
+  end
+
+  def <<(element)
+    @set << element if not @set.include? element
+  end
+
+  def size()
+    @set.size
+  end
+
+  def empty?()
+    @set.empty?
+  end
+
+  def each()
+    @set.each { |element| yield element }
+  end
+
+  def [](filter)
+    result = NumberSet.new
+    each { |element| result << element if filter.test(element) }
+    result
+  end
+end
+
+module SetFilter
+  def &(other)
+    Filter.new { |element| test(element) and other.test(element) }
+  end
+
+  def |(other)
+    Filter.new { |element| test(element) or other.test(element) }
+  end
+end
+
+class Filter
+  include SetFilter
+
+  def initialize(&condition)
+    @condition = condition
+  end
+
+  def test(element)
+    @condition.call(element)
+  end
+end
+
+class SignFilter
+  include SetFilter
+
+  def initialize(sign)
+    @sign = sign
+  end
+
+  def test(element)
+    case @sign
+      when :positive     then element >  0
+      when :non_positive then element <= 0
+      when :negative     then element <  0
+      when :non_negative then element >= 0
+    end
+  end
+end
+
+class TypeFilter
+  include SetFilter
+
+  def initialize(type)
+    @type = type
+  end
+
+  def test(element)
+    case @type
+      when :integer then element.is_a? Integer
+      when :real    then element.is_a? Float or element.is_a? Rational
+      when :complex then element.is_a? Complex
+    end
+  end
+end
Браво, почти си го заковал още от първата версия! Само няколко забележки:
- Изпускай скобите при дефинирането и викането на методи без параметри.
 - Никога 
if not! Има причинаunlessда съществува. (: - Това не е напълно вярна имплементация на 
each. Hint: виж какво би станало, ако го извикаш без блок. Дори и да го оправиш, няма нужда да преоткриваш колелото - можеш да вземеш блока с име вNumberSet#eachи да го предадеш наArray#each. - Предпочитай наследяване пред mixin-ване в общия случай. Можеше 
&и|да ги дефинираш въвFilterи да го наследиш от другите два филтъра. - Има място за подобрение на имената. 
testе предикат, би следвало да завършва на?. Но пак - "тествам множеството с филтъра" не звучи перфектно.NumberSetможе да се имплементира с множество, но съдържа числа. Същото важи и за елементите му.resultе едно от най-generic имената ever. В 99% от случаите има нещо по-конкретно, което да изразява семантиката в дадената ситуация. 
