Class: Attributor::SmartAttributeSelector
- Inherits:
-
Object
- Object
- Attributor::SmartAttributeSelector
- Defined in:
- lib/attributor/smart_attribute_selector.rb
Instance Attribute Summary collapse
-
#accepted ⇒ Object
Returns the value of attribute accepted.
-
#banned ⇒ Object
Returns the value of attribute banned.
-
#keys_with_values ⇒ Object
readonly
Returns the value of attribute keys_with_values.
-
#remaining ⇒ Object
Returns the value of attribute remaining.
-
#reqs ⇒ Object
Returns the value of attribute reqs.
Instance Method Summary collapse
-
#initialize(reqs, attributes, values) ⇒ SmartAttributeSelector
constructor
A new instance of SmartAttributeSelector.
- #process ⇒ Object
- #process_at_least ⇒ Object
- #process_at_least_set(at_least_set, count) ⇒ Object
- #process_at_most ⇒ Object
- #process_at_most_set(set, count) ⇒ Object
- #process_exactly ⇒ Object
- #process_exactly_set(set, count) ⇒ Object
- #process_exclusive ⇒ Object
- #process_exclusive_set(exclusive_set) ⇒ Object
- #process_required ⇒ Object
Constructor Details
#initialize(reqs, attributes, values) ⇒ SmartAttributeSelector
Returns a new instance of SmartAttributeSelector.
6 7 8 9 10 11 12 |
# File 'lib/attributor/smart_attribute_selector.rb', line 6 def initialize( reqs , attributes, values) @reqs = reqs.dup @accepted = [] @banned = [] @remaining = attributes.dup @keys_with_values = values.each_with_object([]){|(k,v),populated| populated.push(k) unless v == nil} end |
Instance Attribute Details
#accepted ⇒ Object
Returns the value of attribute accepted.
3 4 5 |
# File 'lib/attributor/smart_attribute_selector.rb', line 3 def accepted @accepted end |
#banned ⇒ Object
Returns the value of attribute banned.
3 4 5 |
# File 'lib/attributor/smart_attribute_selector.rb', line 3 def banned @banned end |
#keys_with_values ⇒ Object (readonly)
Returns the value of attribute keys_with_values.
4 5 6 |
# File 'lib/attributor/smart_attribute_selector.rb', line 4 def keys_with_values @keys_with_values end |
#remaining ⇒ Object
Returns the value of attribute remaining.
3 4 5 |
# File 'lib/attributor/smart_attribute_selector.rb', line 3 def remaining @remaining end |
#reqs ⇒ Object
Returns the value of attribute reqs.
3 4 5 |
# File 'lib/attributor/smart_attribute_selector.rb', line 3 def reqs @reqs end |
Instance Method Details
#process ⇒ Object
14 15 16 17 18 19 20 21 22 23 24 25 |
# File 'lib/attributor/smart_attribute_selector.rb', line 14 def process process_required process_exclusive process_exactly process_at_least process_at_most # Just add the ones that haven't been explicitly rejected self.accepted += self.remaining self.remaining = [] self.accepted.uniq! self.accepted end |
#process_at_least ⇒ Object
50 51 52 53 54 55 56 57 58 |
# File 'lib/attributor/smart_attribute_selector.rb', line 50 def process_at_least self.reqs = reqs.each_with_object([]) do |req, rest| if req[:type] == :at_least process_at_least_set(Array.new(req[:attributes]), req[:count]) else rest.push req end end end |
#process_at_least_set(at_least_set, count) ⇒ Object
97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 |
# File 'lib/attributor/smart_attribute_selector.rb', line 97 def process_at_least_set( at_least_set, count) feasible = at_least_set - banned # available ones to pick (that are not banned) preferred = (feasible & keys_with_values)[0,count] # Add more if not enough pick = if preferred.size < count preferred + (feasible - preferred)[0,count-preferred.size] else preferred end unless pick.size == count raise UnfeasibleRequirementsError end self.accepted += pick self.remaining -= pick end |
#process_at_most ⇒ Object
60 61 62 63 64 65 66 67 68 |
# File 'lib/attributor/smart_attribute_selector.rb', line 60 def process_at_most self.reqs = reqs.each_with_object([]) do |req, rest| if req[:type] == :at_most && req[:count] > 1 # count=1 is already handled in exclusive process_at_most_set(Array.new(req[:attributes]), req[:count]) else rest.push req end end end |
#process_at_most_set(set, count) ⇒ Object
114 115 116 117 118 119 120 121 122 123 124 125 126 127 |
# File 'lib/attributor/smart_attribute_selector.rb', line 114 def process_at_most_set( set, count) ceil=(count+1)/2 feasible = set - banned # available ones to pick (that are not banned) preferred = (feasible & keys_with_values)[0,ceil] pick = if preferred.size < ceil preferred + (feasible - preferred)[0,(ceil)-preferred.size] else preferred end self.accepted += pick self.remaining -= pick end |
#process_exactly ⇒ Object
70 71 72 73 74 75 76 77 78 |
# File 'lib/attributor/smart_attribute_selector.rb', line 70 def process_exactly self.reqs = reqs.each_with_object([]) do |req, rest| if req[:type] == :exactly && req[:count] > 1 # count=1 is already handled in exclusive process_exactly_set(Array.new(req[:attributes]), req[:count]) else rest.push req end end end |
#process_exactly_set(set, count) ⇒ Object
129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/attributor/smart_attribute_selector.rb', line 129 def process_exactly_set( set, count) feasible = set - banned # available ones to pick (that are not banned) preferred = (feasible & keys_with_values)[0,count] pick = if preferred.size < count preferred + (feasible - preferred)[0,count-preferred.size] else preferred end unless pick.size == count raise UnfeasibleRequirementsError end self.accepted += pick self.remaining -= pick end |
#process_exclusive ⇒ Object
38 39 40 41 42 43 44 45 46 47 48 |
# File 'lib/attributor/smart_attribute_selector.rb', line 38 def process_exclusive self.reqs = reqs.each_with_object([]) do |req, rest| if req[:type] == :exclusive || (req[:type] == :exactly && req[:count] == 1 ) || (req[:type] == :at_most && req[:count] == 1 ) process_exclusive_set(Array.new(req[:attributes])) else rest.push req end end end |
#process_exclusive_set(exclusive_set) ⇒ Object
82 83 84 85 86 87 88 89 90 91 92 93 94 95 |
# File 'lib/attributor/smart_attribute_selector.rb', line 82 def process_exclusive_set( exclusive_set ) feasible = exclusive_set - banned # available ones to pick (that are not banned) # Try to favor attributes that come in with some values, otherwise get the first feasible one preferred = feasible & keys_with_values pick = (preferred.size == 0 ? feasible : preferred).first if pick self.accepted.push( pick ) else raise UnfeasibleRequirementsError unless exclusive_set.empty? end self.banned += (feasible - [pick]) self.remaining -= exclusive_set end |
#process_required ⇒ Object
27 28 29 30 31 32 33 34 35 36 |
# File 'lib/attributor/smart_attribute_selector.rb', line 27 def process_required self.reqs = reqs.each_with_object([]) do |req, rest| if req[:type] == :all self.accepted += req[:attributes] self.remaining -= req[:attributes] else rest.push req end end end |