Теодор обнови решението на 27.10.2014 00:38 (преди около 10 години)
+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
, излишно е в повечето случай, викай директно инстанционните методи. -
eval
IS EVIL. Определено е спомогнал с краткоста на решението, но го промени, тъкмо ще се отървеш и от@sign_type
. - Monkey patching-а на
Proc
също не е добра идея, ако не мислиш като цяло да разширяваш функционалноста на пачваният клас, не го прави. В твоя случей го разширяваш да работи с конкретни класове и е далеч от generic.