Class: Traversal::Description
- Inherits:
-
Object
- Object
- Traversal::Description
- Extended by:
- Forwardable
- Includes:
- Enumerable
- Defined in:
- lib/traversal/description.rb
Overview
Traversal description
Defined Under Namespace
Classes: EmptyArgument
Constant Summary collapse
- DEPTH_FIRST =
0
- BREADTH_FIRST =
1
Instance Attribute Summary collapse
-
#relations ⇒ Object
readonly
Returns the value of attribute relations.
-
#start_node ⇒ Object
readonly
Returns the value of attribute start_node.
Instance Method Summary collapse
-
#==(other) ⇒ Object
Tests equality of traversal descriptions.
-
#breadth_first ⇒ Object
Declare traversal order strategy as breadth first.
-
#breadth_first? ⇒ Boolean
:nodoc:.
-
#depth_first ⇒ Object
Declare traversal order strategy as depth first.
-
#each ⇒ Object
Iterate through nodes defined by DSL and optionally execute given
block
for each node. -
#exclude(*nodes, &blk) ⇒ Object
Declare exclude condition.
-
#exclude_and_prune(*nodes, &blk) ⇒ Object
(also: #prune_and_exclude)
Declare exclude AND prune condition.
-
#exclude_node?(node) ⇒ Boolean
:nodoc:.
-
#expand_node?(node) ⇒ Boolean
:nodoc:.
-
#expand_only(*nodes, &blk) ⇒ Object
Declare which nodes you want to expand.
-
#follow(*relations, &blk) ⇒ Object
Declare which relation you want to follow in your traversal.
-
#include_node?(node) ⇒ Boolean
:nodoc:.
-
#include_only(*nodes, &blk) ⇒ Object
(also: #exclude_unless)
Declare inverted exclude condition.
-
#initialize ⇒ Description
constructor
Create blank traversal description.
-
#prune(*nodes, &blk) ⇒ Object
Declare prune condition.
-
#prune_node?(node) ⇒ Boolean
:nodoc:.
-
#stop?(node, type = :before) ⇒ Boolean
Does node matches one of stop conditions?.
-
#stop_after(*nodes, &blk) ⇒ Object
Declare stop post-condition.
-
#stop_before(*nodes, &blk) ⇒ Object
Declare stop pre-condition.
-
#traverse(start_node) ⇒ Object
Declare a traversal start point.
-
#uniq(v = true) ⇒ Object
Set uniqueness behaviour By default it is set to
true
. -
#uniq? ⇒ Boolean
:nodoc:.
Constructor Details
#initialize ⇒ Description
Create blank traversal description
22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 |
# File 'lib/traversal/description.rb', line 22 def initialize @exclude = [] @include_only = [] @prune = [] @expand_only = [] @stop_before = [] @stop_after = [] @start_node = nil @relations = [] @order = DEPTH_FIRST @uniq = true end |
Instance Attribute Details
#relations ⇒ Object (readonly)
Returns the value of attribute relations.
16 17 18 |
# File 'lib/traversal/description.rb', line 16 def relations @relations end |
#start_node ⇒ Object (readonly)
Returns the value of attribute start_node.
16 17 18 |
# File 'lib/traversal/description.rb', line 16 def start_node @start_node end |
Instance Method Details
#==(other) ⇒ Object
Tests equality of traversal descriptions
39 40 41 42 43 44 45 46 47 |
# File 'lib/traversal/description.rb', line 39 def ==(other) return super unless other.is_a?(Description) [:@start_node, :@relations, :@include_only, :@exclude, :@prune, :@stop_before, :@uniq, :@stop_after, :@order, :@expand_only].all? do |sym| instance_variable_get(sym) == other.instance_variable_get(sym) end end |
#breadth_first ⇒ Object
Declare traversal order strategy as breadth first
127 128 129 |
# File 'lib/traversal/description.rb', line 127 def breadth_first tap { @order = BREADTH_FIRST } end |
#breadth_first? ⇒ Boolean
:nodoc:
177 178 179 |
# File 'lib/traversal/description.rb', line 177 def breadth_first? #:nodoc: @order == BREADTH_FIRST end |
#depth_first ⇒ Object
Declare traversal order strategy as depth first
122 123 124 |
# File 'lib/traversal/description.rb', line 122 def depth_first tap { @order = DEPTH_FIRST } end |
#each ⇒ Object
Iterate through nodes defined by DSL and optionally execute given block
for each node.
138 139 140 141 142 143 144 145 146 147 148 149 150 |
# File 'lib/traversal/description.rb', line 138 def each # :yields: node assert_complete_description iter = Traversal::Iterator.new(self) if iterator? iter.each do |node| yield node end else iter end end |
#exclude(*nodes, &blk) ⇒ Object
Declare exclude condition. Which nodes you want to exclude (ignore them but not their relations) from your traversal?
77 78 79 |
# File 'lib/traversal/description.rb', line 77 def exclude(*nodes, &blk) tap { @exclude << condition(*nodes, &blk) } end |
#exclude_and_prune(*nodes, &blk) ⇒ Object Also known as: prune_and_exclude
Declare exclude AND prune condition. Matching node and its relations will be excluded from traversal.
103 104 105 106 |
# File 'lib/traversal/description.rb', line 103 def exclude_and_prune(*nodes, &blk) exclude(*nodes, &blk) prune(*nodes, &blk) end |
#exclude_node?(node) ⇒ Boolean
:nodoc:
164 165 166 |
# File 'lib/traversal/description.rb', line 164 def exclude_node?(node) #:nodoc: !include_node?(node) end |
#expand_node?(node) ⇒ Boolean
:nodoc:
168 169 170 171 |
# File 'lib/traversal/description.rb', line 168 def (node) #:nodoc: @expand_only.all? { |cond| cond[node] } && @prune.none? { |cond| cond[node] } end |
#expand_only(*nodes, &blk) ⇒ Object
Declare which nodes you want to expand. Others will be pruned.
88 89 90 |
# File 'lib/traversal/description.rb', line 88 def (*nodes, &blk) tap { @expand_only << condition(*nodes, &blk) } end |
#follow(*relations, &blk) ⇒ Object
Declare which relation you want to follow in your traversal. It can be Symbol, Method, Proc or block.
Relation should return something enumerable, otherwise it will be ignored in traversal.
Example
traversal.follow(:children) # for each node will call node#children method
traversal.follow { |node| node.children } # same effect
62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/traversal/description.rb', line 62 def follow(*relations, &blk) raise ArgumentError, 'arguments or block expected' if relations.empty? && !block_given? tap do relations << blk if block_given? relations.each do |relation| @relations << condition(relation) end #@relations = condition(*relations, &blk) end end |
#include_node?(node) ⇒ Boolean
:nodoc:
159 160 161 162 |
# File 'lib/traversal/description.rb', line 159 def include_node?(node) #:nodoc: @include_only.all? { |cond| cond[node] } && @exclude.none? { |cond| cond[node] } end |
#include_only(*nodes, &blk) ⇒ Object Also known as: exclude_unless
Declare inverted exclude condition. Which nodes you want to keep?
82 83 84 |
# File 'lib/traversal/description.rb', line 82 def include_only(*nodes, &blk) tap { @include_only << condition(*nodes, &blk) } end |
#prune(*nodes, &blk) ⇒ Object
Declare prune condition. Which nodes relations you want to ignore?
Example:
traversal.follow(:children).
prune { |node| node.name == "A" } # node "A" will be included, but not its children
97 98 99 |
# File 'lib/traversal/description.rb', line 97 def prune(*nodes, &blk) tap { @prune << condition(*nodes, &blk) } end |
#prune_node?(node) ⇒ Boolean
:nodoc:
173 174 175 |
# File 'lib/traversal/description.rb', line 173 def prune_node?(node) #:nodoc: !(node) end |
#stop?(node, type = :before) ⇒ Boolean
Does node matches one of stop conditions?
155 156 157 |
# File 'lib/traversal/description.rb', line 155 def stop?(node, type = :before) #:nodoc: (type == :after ? @stop_after : @stop_before).any? { |cond| cond[node] } end |
#stop_after(*nodes, &blk) ⇒ Object
Declare stop post-condition. When met, matched node will be included in traversal and iteration will be stopped.
117 118 119 |
# File 'lib/traversal/description.rb', line 117 def stop_after(*nodes, &blk) tap { @stop_after << condition(*nodes, &blk) } end |
#stop_before(*nodes, &blk) ⇒ Object
Declare stop pre-condition. When met, matched node will be excluded from traversal and iteration will be stopped.
111 112 113 |
# File 'lib/traversal/description.rb', line 111 def stop_before(*nodes, &blk) tap { @stop_before << condition(*nodes, &blk) } end |
#traverse(start_node) ⇒ Object
Declare a traversal start point. From which node you want to follow relations?
50 51 52 |
# File 'lib/traversal/description.rb', line 50 def traverse(start_node) tap { @start_node = start_node } end |
#uniq(v = true) ⇒ Object
Set uniqueness behaviour By default it is set to true
133 134 135 |
# File 'lib/traversal/description.rb', line 133 def uniq(v = true) tap { @uniq = !!v } end |
#uniq? ⇒ Boolean
:nodoc:
181 182 183 |
# File 'lib/traversal/description.rb', line 181 def uniq? #:nodoc: @uniq end |