Веселин обнови решението на 06.11.2013 03:28 (преди над 11 години)
+class Todo
+ attr_accessor :status
+ attr_accessor :description
+ attr_accessor :priority
+ attr_accessor :tags
+
+ def initialize arguments
+ @status = arguments[0].strip.downcase.to_sym
+ @description = arguments[1].strip
+ @priority = arguments[2].strip.downcase.to_sym
+ @tags = arguments[3].nil? ? %w[] : arguments[3].split(%r{\s*\,\s*})
+ end
+
+ def contains_all? tag_list
+ tag_list.all?{|tag| @tags.include?(tag)}
+ end
+
+ def equals_status? status
+ @status == status
+ end
+
+ def equals_priority? priority
+ @priority == priority
+ end
+end
+
+class Criteria
+ def self.status symbol
+ [:equals_status?, symbol]
+ end
+
+ def self.priority symbol
+ [:equals_priority?, symbol]
+ end
+
+ def self.tags tag_list
+ [:contains_all?, tag_list]
+ end
+end
+
+class TodoList < Array
+ def initialize(list)
+ super(list)
+ end
+
+ def self.parse text
+ list = TodoList.new []
+ text.each_line(separator=$/)do |line|
+ list << Todo.new(line.split(%r{\s*\|\s*}))
+ end
+ list
+ end
+
+ def filter(criteria=[])
+ hash = Hash[*criteria]
+ list = self.select{ |m| criteria_covered(m, hash) }
+ end
+
+ def criteria_covered(task, hash)
+ hash.all?{ |c, v| task.send(c, v)}
+ end
+
+ def adjoin(other)
+ self | other
+ end
+
+ def tasks_todo
+ self.count{|task| (task.status == :todo)}
+ end
+
+ def tasks_in_progress
+ self.count{|task| task.status == :current}
+ end
+
+ def tasks_completed
+ self.count{|task| task.status == :done}
+ end
+
+ def completed?
+ tasks_completed == self.length
+ end
+end