pacer 1.0.3-java → 1.1.0-java
Sign up to get free protection for your applications and to get access to all the features.
- data/Gemfile +1 -6
- data/lib/{pacer-1.0.3-standalone.jar → pacer-1.1.0-standalone.jar} +0 -0
- data/lib/pacer.rb +4 -0
- data/lib/pacer/blueprints/payload_elements.rb +44 -0
- data/lib/pacer/core/graph.rb +1 -0
- data/lib/pacer/core/graph/element_route.rb +3 -2
- data/lib/pacer/core/graph/path_route.rb +138 -0
- data/lib/pacer/core/route.rb +145 -1
- data/lib/pacer/filter/empty_filter.rb +2 -0
- data/lib/pacer/filter/loop_filter.rb +85 -0
- data/lib/pacer/filter/property_filter/filters.rb +6 -1
- data/lib/pacer/graph/graph_transactions_mixin.rb +6 -1
- data/lib/pacer/graph/pacer_graph.rb +47 -30
- data/lib/pacer/graph/yaml_encoder.rb +2 -0
- data/lib/pacer/loader.rb +9 -0
- data/lib/pacer/pipe/block_filter_pipe.rb +3 -2
- data/lib/pacer/pipe/loop_pipe.rb +23 -17
- data/lib/pacer/pipe/multi_pipe.rb +40 -0
- data/lib/pacer/pipe/naked_pipe.rb +21 -0
- data/lib/pacer/pipe/unwrapping_pipe.rb +4 -0
- data/lib/pacer/pipe/wrapping_pipe.rb +4 -0
- data/lib/pacer/pipes.rb +2 -1
- data/lib/pacer/route/mixin/route_operations.rb +15 -0
- data/lib/pacer/route_builder.rb +8 -11
- data/lib/pacer/side_effect/counted.rb +1 -0
- data/lib/pacer/side_effect/group_count.rb +1 -1
- data/lib/pacer/support/array.rb +18 -0
- data/lib/pacer/support/enumerable.rb +4 -0
- data/lib/pacer/transform/cap.rb +31 -0
- data/lib/pacer/transform/flat_map.rb +9 -0
- data/lib/pacer/transform/make_pairs.rb +29 -0
- data/lib/pacer/transform/map.rb +50 -2
- data/lib/pacer/transform/path.rb +27 -42
- data/lib/pacer/transform/path_tree.rb +111 -0
- data/lib/pacer/transform/payload.rb +50 -0
- data/lib/pacer/transform/process.rb +15 -0
- data/lib/pacer/transform/wrapped_path.rb +23 -0
- data/lib/pacer/utils/graph_analysis.rb +21 -7
- data/lib/pacer/version.rb +1 -1
- data/lib/pacer/wrappers/edge_wrapper.rb +18 -7
- data/lib/pacer/wrappers/element_wrapper.rb +4 -0
- data/lib/pacer/wrappers/index_wrapper.rb +1 -1
- data/lib/pacer/wrappers/path_wrapping_pipe_function.rb +85 -0
- data/lib/pacer/wrappers/vertex_wrapper.rb +33 -3
- data/pom.xml +1 -1
- data/spec/pacer/filter/property_filter/edge_filters_spec.rb +63 -0
- data/spec/pacer/filter/property_filter/filters_spec.rb +17 -7
- data/spec/pacer/transform/join_spec.rb +0 -1
- data/spec/pacer/transform/path_tree_spec.rb +97 -0
- data/spec/spec_helper.rb +2 -2
- metadata +18 -3
data/Gemfile
CHANGED
@@ -13,12 +13,7 @@ group :development do
|
|
13
13
|
# pacer-* gems are required for testing pacer.
|
14
14
|
# If you have the gem repos cloned locally, we'll use them.
|
15
15
|
#
|
16
|
-
|
17
|
-
['pacer-neo4j', '2.0.0.pre'],
|
18
|
-
['pacer-orient', '2.0.0.pre'],
|
19
|
-
['pacer-dex', '2.0.0.pre']
|
20
|
-
]
|
21
|
-
libs.each do |lib, version|
|
16
|
+
[ 'pacer-neo4j', 'pacer-orient', 'pacer-dex'].each do |lib|
|
22
17
|
if File.directory? "../#{lib}"
|
23
18
|
gem lib, :path => "../#{lib}"
|
24
19
|
end
|
Binary file
|
data/lib/pacer.rb
CHANGED
@@ -42,6 +42,10 @@ module Pacer
|
|
42
42
|
require 'pacer/loader'
|
43
43
|
|
44
44
|
class << self
|
45
|
+
def help(section = nil)
|
46
|
+
Pacer.tg.help section
|
47
|
+
end
|
48
|
+
|
45
49
|
# A global place for pacer to put debug info if it's tucked deep in
|
46
50
|
# its internals. Should typically not be used unless a mysterious
|
47
51
|
# bug needs to be analyzed but that never really happens ;)
|
@@ -0,0 +1,44 @@
|
|
1
|
+
module Pacer
|
2
|
+
module Payload
|
3
|
+
class Element
|
4
|
+
include com.tinkerpop.blueprints.Element
|
5
|
+
extend Forwardable
|
6
|
+
|
7
|
+
def initialize(element, payload = nil)
|
8
|
+
@element = element
|
9
|
+
self.payload = payload
|
10
|
+
end
|
11
|
+
|
12
|
+
def inspect
|
13
|
+
"#<Payload #{ element.inspect } -- #{ payload.inspect }>"
|
14
|
+
end
|
15
|
+
|
16
|
+
attr_reader :element
|
17
|
+
attr_accessor :payload
|
18
|
+
end
|
19
|
+
|
20
|
+
class Edge < Element
|
21
|
+
include com.tinkerpop.blueprints.Edge
|
22
|
+
|
23
|
+
def_delegators :@element,
|
24
|
+
# Object
|
25
|
+
:equals, :toString, :hashCode,
|
26
|
+
# Element
|
27
|
+
:getId, :getPropertyKeys, :getProperty, :setProperty, :removeProperty, :getRawElement,
|
28
|
+
# Edge
|
29
|
+
:getLabel, :getVertex, :getRawEdge
|
30
|
+
end
|
31
|
+
|
32
|
+
class Vertex < Element
|
33
|
+
include com.tinkerpop.blueprints.Vertex
|
34
|
+
|
35
|
+
def_delegators :@element,
|
36
|
+
# Object
|
37
|
+
:equals, :toString, :hashCode,
|
38
|
+
# Element
|
39
|
+
:getId, :getPropertyKeys, :getProperty, :setProperty, :removeProperty, :getRawElement,
|
40
|
+
# Vertex
|
41
|
+
:getEdges, :getVertices, :query, :getRawVertex
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
data/lib/pacer/core/graph.rb
CHANGED
@@ -40,8 +40,9 @@ module Pacer::Core::Graph
|
|
40
40
|
# Create a new TinkerGraph based on the paths of all matching elements.
|
41
41
|
#
|
42
42
|
# @return [TinkerGraph] the subgraph
|
43
|
-
def subgraph opts = {}
|
44
|
-
|
43
|
+
def subgraph(graph = nil, opts = {})
|
44
|
+
graph, opts = [nil, graph] if graph.is_a? Hash
|
45
|
+
paths.subgraph graph, opts
|
45
46
|
end
|
46
47
|
|
47
48
|
# Delete all matching elements.
|
@@ -0,0 +1,138 @@
|
|
1
|
+
module Pacer::Core::Graph
|
2
|
+
module PathRoute
|
3
|
+
def help(section = nil)
|
4
|
+
case section
|
5
|
+
when :paths
|
6
|
+
puts <<HELP
|
7
|
+
The following path helper methods are available:
|
8
|
+
|
9
|
+
#transpose Works the same as Array transpase
|
10
|
+
|
11
|
+
#subgraph(target_graph, opts) Add each element in the path to the graph
|
12
|
+
target_graph: PacerGraph (optional) if not specified creates a new TG.
|
13
|
+
opts:
|
14
|
+
create_vertices: Boolean Create vertices for edges if needed
|
15
|
+
Edges can not be created without both vertices being present. If
|
16
|
+
this option is not set and a vertex is missing, raises a
|
17
|
+
Pacer::ElementNotFound exception.
|
18
|
+
ignore_missing_vertices: Boolean Squelches the above mentioned exception
|
19
|
+
show_missing_vertices: Boolean Complain about missing vertices
|
20
|
+
|
21
|
+
#compact_paths Removes nils from paths
|
22
|
+
|
23
|
+
#heads Route to only the first element from each path
|
24
|
+
|
25
|
+
#tails Route to only the last element from each path
|
26
|
+
|
27
|
+
#pairs(head, tail) Route to a mini path of only the first and last elements
|
28
|
+
head: Number Array index of the : first : element in the pair
|
29
|
+
tail: Number : second :
|
30
|
+
|
31
|
+
#len(n) Filter paths by length
|
32
|
+
n: Number | Range
|
33
|
+
|
34
|
+
#hashify Make a hash of the properties and relationships of the path
|
35
|
+
This is just a simple view on the data to facilitate analysis
|
36
|
+
|
37
|
+
HELP
|
38
|
+
else
|
39
|
+
super
|
40
|
+
end
|
41
|
+
description
|
42
|
+
end
|
43
|
+
|
44
|
+
def transpose
|
45
|
+
collect { |arraylist| arraylist.to_a }.transpose
|
46
|
+
end
|
47
|
+
|
48
|
+
def subgraph(target_graph = nil, opts = {})
|
49
|
+
raise "Can't create a subgraph within itself." if target_graph == graph
|
50
|
+
target_graph ||= Pacer.tg
|
51
|
+
target_graph.vertex_name ||= graph.vertex_name
|
52
|
+
missing_edges = Set[]
|
53
|
+
bulk_job(nil, target_graph) do |path|
|
54
|
+
path.select { |e| e.is_a? Pacer::Vertex }.each do |vertex|
|
55
|
+
vertex.clone_into target_graph
|
56
|
+
end
|
57
|
+
path.select { |e| e.is_a? Pacer::Edge }.each do |edge|
|
58
|
+
unless edge.clone_into target_graph, ignore_missing_vertices: true
|
59
|
+
missing_edges << edge
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
if missing_edges.any?
|
64
|
+
missing_edges.to_route(graph: graph, element_type: :edge).bulk_job nil, target_graph do |edge|
|
65
|
+
edge.clone_into target_graph,
|
66
|
+
ignore_missing_vertices: opts[:ignore_missing_vertices],
|
67
|
+
show_missing_vertices: opts[:show_missing_vertices]
|
68
|
+
end
|
69
|
+
end
|
70
|
+
target_graph
|
71
|
+
end
|
72
|
+
|
73
|
+
def payloads
|
74
|
+
map element_type: :path, route_name: 'payloads' do |path|
|
75
|
+
path.map do |e|
|
76
|
+
if e.is_a? Pacer::Payload::Element
|
77
|
+
e.payload
|
78
|
+
elsif e.is_a? Pacer::Wrappers::ElementWrapper
|
79
|
+
e.element_payload
|
80
|
+
end
|
81
|
+
end
|
82
|
+
end
|
83
|
+
end
|
84
|
+
|
85
|
+
def compact_paths
|
86
|
+
map element_type: :path, route_name: 'compact' do |path|
|
87
|
+
path.compact
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
def heads(et = :vertex)
|
92
|
+
map element_type: et, route_name: 'heads' do |path|
|
93
|
+
path.first
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def tails(et = :vertex)
|
98
|
+
map element_type: et, route_name: 'tails' do |path|
|
99
|
+
path.last
|
100
|
+
end
|
101
|
+
end
|
102
|
+
|
103
|
+
def pairs(head = 0, tail = -1)
|
104
|
+
map element_type: :path, route_name: "pairs[#{ head },#{ tail }]" do |path|
|
105
|
+
[path[head], path[tail]]
|
106
|
+
end
|
107
|
+
end
|
108
|
+
|
109
|
+
def len(n)
|
110
|
+
select do |path|
|
111
|
+
n === path.length
|
112
|
+
end
|
113
|
+
end
|
114
|
+
|
115
|
+
def hashify
|
116
|
+
map(element_type: :hash, route_name: 'trees') do |path|
|
117
|
+
path.to_a.reverse.reduce({}) do |tree, element|
|
118
|
+
if element.element_type == :vertex
|
119
|
+
tree.merge element.properties
|
120
|
+
else
|
121
|
+
{ element.label => [tree] }
|
122
|
+
end
|
123
|
+
end
|
124
|
+
end
|
125
|
+
end
|
126
|
+
protected
|
127
|
+
|
128
|
+
def configure_iterator(iter)
|
129
|
+
if respond_to? :graph
|
130
|
+
pipe = Pacer::Pipes::PathWrappingPipe.new(graph)
|
131
|
+
pipe.setStarts iter
|
132
|
+
pipe
|
133
|
+
else
|
134
|
+
iter
|
135
|
+
end
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/lib/pacer/core/route.rb
CHANGED
@@ -156,6 +156,148 @@ module Pacer
|
|
156
156
|
nil
|
157
157
|
end
|
158
158
|
|
159
|
+
def help(section = nil)
|
160
|
+
general_topics = <<HELP
|
161
|
+
Some general help sections:
|
162
|
+
:routes What are Pacer's routes?
|
163
|
+
:basics Simple usage examples
|
164
|
+
:creation How to create records
|
165
|
+
:tools Some things you can do
|
166
|
+
:graphs Available graphs
|
167
|
+
:help How to contribute to Pacer's inline help
|
168
|
+
HELP
|
169
|
+
if section == :help
|
170
|
+
puts <<HELP
|
171
|
+
Contributions of help topics will be greatly apreciated.
|
172
|
+
|
173
|
+
Help topics should be added to the modules that they describe. General topics
|
174
|
+
help can be added here for now but will likely be moved eventually.
|
175
|
+
|
176
|
+
See lib/pacer/transform/map.rb for an example of how to define contextual help
|
177
|
+
topics.
|
178
|
+
|
179
|
+
If you add a general topic, remember to add it to the list above.
|
180
|
+
|
181
|
+
Remember to call super for unrecognized sections! :)
|
182
|
+
|
183
|
+
HELP
|
184
|
+
elsif section == :routes
|
185
|
+
puts <<HELP
|
186
|
+
Pacer's routes are a very efficient and fast way to deal with data.
|
187
|
+
|
188
|
+
The fundamental thing about them is that they are lazily evaluated, which
|
189
|
+
allows very expensive traversals to be defined, yet nearly always produces
|
190
|
+
results immediately with very low memory requirements, too.
|
191
|
+
|
192
|
+
|
193
|
+
|
194
|
+
HELP
|
195
|
+
elsif section == :basics
|
196
|
+
puts <<HELP
|
197
|
+
Pacer basics:
|
198
|
+
|
199
|
+
g = Pacer.tg # create an in-memory graph
|
200
|
+
# - help(:graphs) for other types
|
201
|
+
g.v # create a route to all vertices in the graph
|
202
|
+
# vertices are your basic documents.
|
203
|
+
g.e # ... or all edges
|
204
|
+
# edges connect documents. They can have properties, too!
|
205
|
+
g.v(name: 'Sue', gender: 'male') # find all boys named Sue
|
206
|
+
# all elements are schemaless, so you
|
207
|
+
# can specify any properties
|
208
|
+
g.v(name: 'Sue', gender: 'male').count # how many are there?
|
209
|
+
# see how we can chain calls? Powerful
|
210
|
+
# traversals can be defined this way.
|
211
|
+
g.v.out_e(:friend) # see Sue's 'friend' relationships
|
212
|
+
g.v.out_e(:friend).in_v # continue on to his friends
|
213
|
+
g.v.out_e(:friend).in_v.out(:friends) # continue on to his friends-of-friends
|
214
|
+
g.v.in(:friend) # see who has friended Sue.
|
215
|
+
# all edges are directional to follow an
|
216
|
+
# edge, use #out or #out_e; to go
|
217
|
+
# backwards along an edge, use #in or
|
218
|
+
# #in_e
|
219
|
+
|
220
|
+
#{general_topics}
|
221
|
+
|
222
|
+
HELP
|
223
|
+
elsif section == :creation
|
224
|
+
puts <<HELP
|
225
|
+
How we can create records in a Pacer graph:
|
226
|
+
|
227
|
+
g = Pacer.tg # create a new in-memory graph to play with
|
228
|
+
sue = g.create_vertex name: 'Sue', gender: 'male'
|
229
|
+
# create a record with properties
|
230
|
+
ghost = g.create_vertex # get lazy and create an empty one
|
231
|
+
sue.add_edges_to :friend, ghost # Sue has friended the ghost.
|
232
|
+
# This relationship can be traversed in
|
233
|
+
# both directions so a reverse
|
234
|
+
# relationship is *not* required, but can
|
235
|
+
# be created:
|
236
|
+
ghost.add_edges_to :friend, sue, type: 'spooky'
|
237
|
+
# We can also create edges with properties
|
238
|
+
sue[:age] = 27 # It's that easy to add or change a property
|
239
|
+
sue['fav foods'] = [pie, donuts] # Pacer can shoehorn any data into the
|
240
|
+
# graph as long as it's serializable.
|
241
|
+
|
242
|
+
#{general_topics}
|
243
|
+
|
244
|
+
HELP
|
245
|
+
elsif section == :tools
|
246
|
+
puts <<HELP
|
247
|
+
|
248
|
+
HELP
|
249
|
+
elsif section == :graphs or section == :plugins
|
250
|
+
puts <<HELP
|
251
|
+
Various graphs are supported in their own Rubygems. Check out pacer-neo4j,
|
252
|
+
pacer-orient, pacer-dex for now. New graphs emerge frequently and I hope to
|
253
|
+
support many of them.
|
254
|
+
|
255
|
+
Search rubygems.org or github for projects that start with "pacer-" to see what
|
256
|
+
other plugins exist as well.
|
257
|
+
|
258
|
+
#{general_topics}
|
259
|
+
|
260
|
+
HELP
|
261
|
+
else
|
262
|
+
if section
|
263
|
+
puts "Unrecognized help section specified"
|
264
|
+
puts
|
265
|
+
elsif not is_a? Graph
|
266
|
+
puts "No specialized help has been defined for this step yet."
|
267
|
+
puts
|
268
|
+
end
|
269
|
+
puts <<HELP
|
270
|
+
How to use Pacer's inline help:
|
271
|
+
|
272
|
+
You can use Pacer.help(:section) to print help on general topics, or get
|
273
|
+
context-specific help by calling help on any route. For example:
|
274
|
+
|
275
|
+
graph.v.out_e.map.help # will give you help about the map command.
|
276
|
+
|
277
|
+
#{general_topics}
|
278
|
+
|
279
|
+
General options (may not be available for all methods)
|
280
|
+
|
281
|
+
element_type: Symbol Set what type of element is emitted from this step.
|
282
|
+
registered types: #{ Pacer::RouteBuilder.current.element_types.keys.map(&:inspect).join ', ' }
|
283
|
+
|
284
|
+
graph: PacerGraph If the route contains graph elements, specify that they
|
285
|
+
are from this graph
|
286
|
+
|
287
|
+
route_name: String Name for this route when inspecting it in IRB.
|
288
|
+
|
289
|
+
info: String Put what you want here. Appears when the route is inspected.
|
290
|
+
|
291
|
+
extensions: [Module] Extra extensions to add to the route.
|
292
|
+
|
293
|
+
wrapper: Class Wrap elements in this class.
|
294
|
+
For each element, wrapper.new(graph, element) happens
|
295
|
+
|
296
|
+
HELP
|
297
|
+
end
|
298
|
+
description
|
299
|
+
end
|
300
|
+
|
159
301
|
def description(join = ' -> ')
|
160
302
|
"#<#{inspect_strings.join(join)}>"
|
161
303
|
end
|
@@ -308,7 +450,9 @@ module Pacer
|
|
308
450
|
# @return [java.util.Iterator]
|
309
451
|
def source_iterator
|
310
452
|
if @source
|
311
|
-
iterator_from_source(@source)
|
453
|
+
iter = iterator_from_source(@source)
|
454
|
+
iter.enablePath(true) if iter.respond_to? :enablePath
|
455
|
+
iter
|
312
456
|
elsif @back
|
313
457
|
@back.send(:source_iterator)
|
314
458
|
end
|
@@ -47,6 +47,91 @@ module Pacer
|
|
47
47
|
attr_reader :looping_route
|
48
48
|
attr_accessor :while_description
|
49
49
|
|
50
|
+
def help(section = nil)
|
51
|
+
case section
|
52
|
+
when nil
|
53
|
+
puts <<HELP
|
54
|
+
Loops allow you to define repetative paths and paths of indeterminate length.
|
55
|
+
As a path is expanded within a loop, a control block that you define can
|
56
|
+
determine whether the given vertex should be emitted or not and whether it
|
57
|
+
should be used to continue looping or not.
|
58
|
+
|
59
|
+
There are two minor variations of the loop pipe. This is much more efficient
|
60
|
+
because it does not need to keep track of every element's path.
|
61
|
+
|
62
|
+
g.v.
|
63
|
+
loop { |route| route.out_e.in_v }.
|
64
|
+
while { |element, depth| :loop_and_emit }
|
65
|
+
|
66
|
+
This is less efficient but having the path available to you can be very
|
67
|
+
powerful:
|
68
|
+
|
69
|
+
g.v.
|
70
|
+
loop { |route| route.out_e.in_v }.
|
71
|
+
while { |element, depth, path| :loop_and_emit }
|
72
|
+
|
73
|
+
Control block arguments:
|
74
|
+
element - the element that could be emitted or looped on
|
75
|
+
depth - each initial element is depth 0 and has not had the loop route applied to it yet.
|
76
|
+
path - (optional) the full array of elements that got us to where we are
|
77
|
+
|
78
|
+
From the while block, you can give back one of three symbols:
|
79
|
+
:loop - loop on this element; don't include it in results
|
80
|
+
:emit - don't loop on this element; include it in the results
|
81
|
+
:discard - don't loop on this element; don't include it in the results
|
82
|
+
:loop_and_emit - loop on this element and include it in the results
|
83
|
+
|
84
|
+
In addition:
|
85
|
+
false | nil - maps to :discard
|
86
|
+
anything else - maps to :loop_and_emit
|
87
|
+
|
88
|
+
See the :examples section for some interesting ways to use the loop pipe.
|
89
|
+
|
90
|
+
HELP
|
91
|
+
when :examples
|
92
|
+
puts <<HELP
|
93
|
+
Range from 1 to 9:
|
94
|
+
|
95
|
+
[1].to_route.loop { |r| r.map { |n| n + 1 } }.while { |n, depth| n < 10 }
|
96
|
+
#==> 1 2 3 4 5 6 7 8 9
|
97
|
+
|
98
|
+
Why didn't this give me even numbers?
|
99
|
+
|
100
|
+
[1].to_route.loop { |r| r.map { |n| n + 1 } }.while { |n, depth| n.even? ? :emit : :emit_and_loop }
|
101
|
+
#==> 1 2
|
102
|
+
|
103
|
+
Odd numbers:
|
104
|
+
|
105
|
+
[1].to_route.loop { |r| r.map { |n| n + 1 } }.while { |n, depth| n.even? ? :loop : :emit_and_loop }.limit(10)
|
106
|
+
#==> 1 3 5 7 9 11 13 15 17 19
|
107
|
+
|
108
|
+
Fibonacci sequence:
|
109
|
+
|
110
|
+
[[0, 1]].to_route(element_type: :path).
|
111
|
+
loop { |r| r.map { |a, b| [b, a+b] } }.
|
112
|
+
while { true }.limit(40).
|
113
|
+
tails(element_type: :number)
|
114
|
+
#==> 1 1 2 3 5 8 13 21
|
115
|
+
#==> 34 55 89 144 233 377 610 987
|
116
|
+
#==> 1597 2584 4181 6765 10946 17711 28657 46368
|
117
|
+
#==> 75025 121393 196418 317811 514229 832040 1346269 2178309
|
118
|
+
#==> 3524578 5702887 9227465 14930352 24157817 39088169 63245986 102334155
|
119
|
+
|
120
|
+
You usually won't mean to do these, but you can:
|
121
|
+
|
122
|
+
[1].to_route.loop { |r| 123 }.while { true }.limit(10)
|
123
|
+
#==> 123 123 123 123 123 123 123 123 123 123
|
124
|
+
|
125
|
+
[1].to_route.loop { |r| r }.while { true }.limit(10)
|
126
|
+
#==> 1 1 1 1 1 1 1 1 1 1
|
127
|
+
|
128
|
+
HELP
|
129
|
+
else
|
130
|
+
super
|
131
|
+
end
|
132
|
+
description
|
133
|
+
end
|
134
|
+
|
50
135
|
def looping_route=(route)
|
51
136
|
if route.is_a? Proc
|
52
137
|
@looping_route = Pacer::Route.block_branch(self, route)
|