Module: Pacer::Filter::LoopFilter

Defined in:
lib/pacer/filter/loop_filter.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#looping_routeObject

Returns the value of attribute looping_route.



62
63
64
# File 'lib/pacer/filter/loop_filter.rb', line 62

def looping_route
  @looping_route
end

#reverse_emit_routeObject (readonly)

Returns the value of attribute reverse_emit_route.



64
65
66
# File 'lib/pacer/filter/loop_filter.rb', line 64

def reverse_emit_route
  @reverse_emit_route
end

#reverse_loop_routeObject (readonly)

Returns the value of attribute reverse_loop_route.



64
65
66
# File 'lib/pacer/filter/loop_filter.rb', line 64

def reverse_loop_route
  @reverse_loop_route
end

#while_descriptionObject

Returns the value of attribute while_description.



63
64
65
# File 'lib/pacer/filter/loop_filter.rb', line 63

def while_description
  @while_description
end

Instance Method Details

#deepest!Object

this could have concurrency problems if multiple instances of the same route



166
167
168
169
170
171
172
# File 'lib/pacer/filter/loop_filter.rb', line 166

def deepest!
  @loop_when_route = @looping_route
  @reverse_loop_route = false
  @emit_when_route = @looping_route
  @reverse_emit_route = true
  self
end

#emit_when(&block) ⇒ Object



186
187
188
189
190
# File 'lib/pacer/filter/loop_filter.rb', line 186

def emit_when(&block)
  @emit_when_route = Pacer::Route.block_branch(self, block)
  @reverse_emit_route = false
  self
end

#emit_when_not(&block) ⇒ Object



192
193
194
195
196
# File 'lib/pacer/filter/loop_filter.rb', line 192

def emit_when_not(&block)
  @emit_when_route = Pacer::Route.block_branch(self, block)
  @reverse_emit_route = true
  self
end

#help(section = nil) ⇒ Object



66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
# File 'lib/pacer/filter/loop_filter.rb', line 66

def help(section = nil)
  case section
  when nil
    puts <<HELP
Loops allow you to define repetative paths and paths of indeterminate length.
As a path is expanded within a loop, a control block that you define can
determine whether the given vertex should be emitted or not and whether it
should be used to continue looping or not.

There are two minor variations of the loop pipe. This is much more efficient
because it does not need to keep track of every element's path.

  g.v.
    loop { |route| route.out_e.in_v }.
    while { |element, depth| :loop_and_emit }

This is less efficient but having the path available to you can be very
powerful:

  g.v.
    loop { |route| route.out_e.in_v }.
    while { |element, depth, path| :loop_and_emit }

Control block arguments:
  element         - the element that could be emitted or looped on
  depth           - each initial element is depth 0 and has not had the loop route applied to it yet.
  path            - (optional) the full array of elements that got us to where we are

From the while block, you can give back one of three symbols:
  :loop           - loop on this element; don't include it in results
  :emit           - don't loop on this element; include it in the results
  :discard        - don't loop on this element; don't include it in the results
  :loop_and_emit  - loop on this element and include it in the results

In addition:
  false | nil     - maps to :discard
  anything else   - maps to :loop_and_emit

See the :examples section for some interesting ways to use the loop pipe.

HELP
  when :examples
    puts <<HELP
Range from 1 to 9:

  [1].to_route.loop { |r| r.map { |n| n + 1 } }.while { |n, depth| n < 10 }
  #==> 1 2 3 4 5 6 7 8 9

Why didn't this give me even numbers?

  [1].to_route.loop { |r| r.map { |n| n + 1 } }.while { |n, depth| n.even? ? :emit : :emit_and_loop }
  #==> 1 2

Odd numbers:

  [1].to_route.loop { |r| r.map { |n| n + 1 } }.while { |n, depth| n.even? ? :loop : :emit_and_loop }.limit(10)
  #==> 1  3  5  7  9  11 13 15 17 19

Fibonacci sequence:

  [[0, 1]].to_route(element_type: :path).
    loop { |r| r.map { |a, b| [b, a+b] } }.
    while { true }.limit(40).
    tails(element_type: :number)
  #==> 1         1         2         3         5         8         13        21
  #==> 34        55        89        144       233       377       610       987
  #==> 1597      2584      4181      6765      10946     17711     28657     46368
  #==> 75025     121393    196418    317811    514229    832040    1346269   2178309
  #==> 3524578   5702887   9227465   14930352  24157817  39088169  63245986  102334155

You usually won't mean to do these, but you can:

  [1].to_route.loop { |r| 123 }.while { true }.limit(10)
  #==> 123 123 123 123 123 123 123 123 123 123

  [1].to_route.loop { |r| r }.while { true }.limit(10)
  #==> 1 1 1 1 1 1 1 1 1 1

HELP
  else
    super
  end
  description
end

#loop_when(&block) ⇒ Object



174
175
176
177
178
# File 'lib/pacer/filter/loop_filter.rb', line 174

def loop_when(&block)
  @loop_when_route = Pacer::Route.block_branch(self, block)
  @reverse_loop_route = false
  self
end

#loop_when_not(&block) ⇒ Object



180
181
182
183
184
# File 'lib/pacer/filter/loop_filter.rb', line 180

def loop_when_not(&block)
  @loop_when_route = Pacer::Route.block_branch(self, block)
  @reverse_loop_route = true
  self
end

#while(&block) ⇒ Object



159
160
161
162
# File 'lib/pacer/filter/loop_filter.rb', line 159

def while(&block)
  @control_block = block
  self
end