Ангел обнови решението на 23.10.2014 00:34 (преди около 10 години)
+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% от случаите има нещо по-конкретно, което да изразява семантиката в дадената ситуация.