class Noteikumi::State
The state a rule will process, this is not a state machine but rather can be thought of like a scope
Attributes
The engine this state is associated with @api private @return [Engine]
The logger used @api private @return [Logger]
Set the state mutable or not @return [Boolean]
A list of rules that acted on this state @return [Array<Rule>]
The list of result obtained from each rule @return [Array<Result>]
Public Class Methods
Creates a new state
@param engine [Engine] @param logger [Logger] @return [State]
# File lib/noteikumi/state.rb, line 32 def initialize(engine, logger) @items = {} @results = [] @processed_by = [] @engine = engine @logger = logger @mutable = true end
Public Instance Methods
Adds an item
See {#set} for a version of this that does not error if the item is already on the state
@param item [Symbol] item to delete @param value [Object] item to store @return [Object] the value set @raise [StandardError] when the state is not mutable @raise [StandardError] when the item is already in the state
# File lib/noteikumi/state.rb, line 217 def add(item, value) raise("State is not mustable") unless mutable? raise("Already have item %s" % item) if has?(item) set(item, value) end
Adds a result to the list of results
@param result [Result] @return [Result]
# File lib/noteikumi/state.rb, line 82 def add_result(result) @results << result if result end
Allow the state to be modified
@return [void]
# File lib/noteikumi/state.rb, line 44 def allow_mutation @mutable = true end
Deletes an item
@param item [Symbol] item to delete @raise [StandardError] when the state is not mutable
# File lib/noteikumi/state.rb, line 201 def delete(item) raise("State is not mustable") unless mutable? @items.delete(item) end
Yields each recorded result
@yieldparam result [Result] for every rule that ran @return [void]
# File lib/noteikumi/state.rb, line 72 def each_result @results.each do |result| yield(result) end end
Retrieves a item from the state
@param item [Symbol] the item name @return [Object,nil] the value stored
# File lib/noteikumi/state.rb, line 228 def get(item) @items[item] end
Checks all results for failures
@return [Boolean] true when there were failures
# File lib/noteikumi/state.rb, line 89 def had_failures? @results.map(&:error?).include?(true) end
Determines if any item in the State
has a certain type
@param type [Class] a ruby class to look for @return [Boolean]
# File lib/noteikumi/state.rb, line 149 def has_item_of_type?(type) !items_by_type(type).empty? end
Checks if a item is in the state
@param item [Symbol] item name @return [Boolean]
# File lib/noteikumi/state.rb, line 179 def include?(item) @items.include?(item) end
Selects any item that has a certain ruby class type
@param type [Class] the type to search for @return [Hash] items found
# File lib/noteikumi/state.rb, line 109 def items_by_type(type) @items.select {|_, v| v.is_a?(type)} || [] end
Checks if a given requirement is matched by this state
@example
state[:one] = "hello world" state.meets_requirements?(:one, String) => [true, "reason"] state.meets_requirements?(nil, String) => [true, "reason"] state.meets_requirements?(nil, Fixnum) => [false, "State has no items of class Fixnum"] state.meets_requirements?(:one, Fixnum) => [false, "State item :one is not a Fixnum"] state.meets_requirements?(:not_set, Fixnum) => [false, "State has no item not_set"]
@param requirement [Array<key,type>] @return [Array<Boolean,String>]
# File lib/noteikumi/state.rb, line 127 def meets_requirement?(requirement) key, klass = requirement if key return([false, "State has no item %s" % key]) unless include?(key) unless self[key].is_a?(klass) return [false, "State item %s is not a %s" % [key, klass]] end end unless has_item_of_type?(klass) return [false, "State has no items of class %s" % klass] end [true, "Valid state found"] end
Determines if the state can be mutated
# File lib/noteikumi/state.rb, line 154 def mutable? !!@mutable end
Prevent the state from being modified
@return [void]
# File lib/noteikumi/state.rb, line 51 def prevent_mutation @mutable = false end
Process a rule with the state
@return [Result, nil] nil when the rule did not run
# File lib/noteikumi/state.rb, line 58 def process_rule(rule) rule.concurrent_safe? ? prevent_mutation : allow_mutation result = rule.process(self) allow_mutation record_rule(rule, result) end
Determines if a rule with a specific name acted on this state
@param rule [Rule,Symbol] the rule name or a rule @return [Boolean]
# File lib/noteikumi/state.rb, line 97 def processed_by?(rule) if rule.is_a?(Rule) @processed_by.include?(rule) else @processed_by.map(&:name).include?(rule) end end
Records a rule having acted on this state
If the result is not nil the actor will be record and the result stored, else it’s a noop
@param rule [Rule] @param result [Result] @return [void]
# File lib/noteikumi/state.rb, line 166 def record_rule(rule, result) if result @processed_by << rule @results << result end result end
sets the value of an item without checking if it’s already set
@param item [Symbol] the name of the item being stored @param value [Object] the item to store @return [Object] the item being stored @raise [StandardError] when the state is not mutable
# File lib/noteikumi/state.rb, line 190 def set(item, value) raise("State is not mustable") unless mutable? @items[item] = value end