Module: Pacer::Core::Route

Included in:
DexGraph, Neo4jGraph, Route, Routes::ContextRoute, Routes::PathsRoute, TinkerGraph
Defined in:
lib/pacer/core/route.rb,
lib/pacer/support/iterator_mixins.rb,
lib/pacer/filter/collection_filter.rb

Overview

The basic internal logic for routes and core route shared methods are defined here. Many of these methods are designed to be specialized by other modules included after Core::Route is included.

Defined Under Namespace

Modules: IteratorBlockMixin, IteratorContextMixin, IteratorExtensionsMixin, IteratorPathMixin

Instance Attribute Summary collapse

Instance Method Summary collapse

Instance Attribute Details

#graphGraphMixin

TODO:

move this to graph routes.

Return which graph this route operates on.



38
39
40
# File 'lib/pacer/core/route.rb', line 38

def graph
  @graph ||= (@back || @source).graph rescue nil
end

#hide_elementstrue, false

If true, elements won't be printed to STDOUT when #inspect is called on this route.



26
27
28
# File 'lib/pacer/core/route.rb', line 26

def hide_elements
  @hide_elements
end

#pipe_args[Object] #pipe_args=(args) ⇒ [Object] #pipe_args=(args) ⇒ [Object]

The arguments passed to the pipe constructor.



56
57
58
# File 'lib/pacer/core/route.rb', line 56

def pipe_args
  @pipe_args
end

#pipe_classObject

Specify which pipe class will be instantiated when an iterator is created.



21
22
23
# File 'lib/pacer/core/route.rb', line 21

def pipe_class
  @pipe_class
end

#route_nameObject

Replace the generated class name of this route with a specific one by setting route_name.



18
19
20
# File 'lib/pacer/core/route.rb', line 18

def route_name
  @route_name
end

Instance Method Details

#-(other) ⇒ Object



12
13
14
# File 'lib/pacer/filter/collection_filter.rb', line 12

def -(other)
  chain_route :filter => :collection, :except => other
end

#==(other) ⇒ true, false

Returns true if the other route is defined the same as the current route.

Note that block filters will prevent matches even with identically defined routes unless the routes are actually the same object.



270
271
272
273
274
275
276
# File 'lib/pacer/core/route.rb', line 270

def ==(other)
  other.class == self.class and
    other.function == function and
    other.element_type == element_type and
    other.back == back and
    other.source == source
end

#add_extension(mod) ⇒ self

Add an extension to the route.

If the extension has a Route module inside it, this route will be extended with the extension's Route module.

If the extension has a Vertex or Edge module inside it, any vertices or edges emitted from this route will be extended with with the extension as well.



296
297
298
299
300
301
302
303
304
305
306
307
# File 'lib/pacer/core/route.rb', line 296

def add_extension(mod)
  return self unless mod.respond_to?(:const_defined?)
  is_extension = false
  if mod.const_defined? :Route
    is_extension = true
    extend mod::Route
  end
  if is_extension or mod.const_defined? :Vertex or mod.const_defined? :Edge
    extensions << mod
  end
  self
end

#add_extensions(exts) ⇒ self

If any objects in the given array are modules that contain a Route submodule, extend this route with the Route module.

See Also:



327
328
329
330
331
332
333
# File 'lib/pacer/core/route.rb', line 327

def add_extensions(exts)
  modules = exts.select { |obj| obj.is_a? Module or obj.is_a? Class }
  modules.each do |mod|
    add_extension(mod)
  end
  self
end

#each_context {|ElementMixin(Extensions::BlockFilterElement)| ... } ⇒ Enumerator(IteratorContextMixin)

TODO:

move with graph-specific code or make more general.

Iterates over each element resulting from traversing the route up to this point. Extends each element with Extensions::BlockFilterElement to make route context available.

Yields:



188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
# File 'lib/pacer/core/route.rb', line 188

def each_context
  iter = iterator
  if block_given?
    g = graph
    while true
      item = iter.next
      item.graph ||= g
      item.extend Pacer::Extensions::BlockFilterElement
      item.back = self
      yield item
    end
  else
    iter.extend IteratorContextMixin
    iter.graph = graph
    iter.context = self
    iter
  end
rescue java.util.NoSuchElementException
  self
end

#each_element {|item| ... } ⇒ Enumerator

TODO:

move with graph-specific code or make more general.

Iterates over each element resulting from traversing the route up to this point.

Yields:

  • (item)

    if a block is given



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
# File 'lib/pacer/core/route.rb', line 109

def each_element
  iter = iterator
  g = graph
  if extensions.empty?
    if block_given?
      while true
        item = iter.next
        item.graph ||= g if g and item.respond_to? :graph=
        yield item
      end
    else
      iter
    end
  else
    if block_given?
      while true
        item = iter.next
        if item.respond_to? :graph=
          item.graph ||= g if g and item.respond_to? :graph=
          item = item.add_extensions(extensions)
        end
        yield item
      end
    else
      iter.extend IteratorExtensionsMixin
      iter.graph = g
      iter.extensions = extensions
      iter
    end
  end
rescue java.util.NoSuchElementException
  self
end

#each_object {|Object| ... } ⇒ Enumerator

Iterates over each object resulting from traversing the route up to this point.

Yields:

  • (Object)

    if a block is given



214
215
216
217
218
219
220
221
222
223
224
225
226
# File 'lib/pacer/core/route.rb', line 214

def each_object
  iter = iterator
  if block_given?
    while true
      item = iter.next
      yield item
    end
  else
    iter
  end
rescue java.util.NoSuchElementException
  self
end

#each_path {|java.util.List[Object]| ... } ⇒ Enumerator[Object]

Iterates over each path resulting from traversing the route up to this point.

The path should contain each element that has been produced by each step in the pipeline that the route constructs. That means that it is possible that single step in the overall route may produce 0..many elements in the path (though the typical number is 1). Also note that if an element is emitted by multiple steps in a row it will only appear in the route once in that position. On the other hand if a single element appears more than once in at different times during a traversal, it will appear multiple times in the path.

Yields:

  • (java.util.List[Object])

    if a block is given



158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
# File 'lib/pacer/core/route.rb', line 158

def each_path
  iter = iterator
  if block_given?
    g = graph
    while true
      item = iter.next
      path = iter.path.collect do |e|
        e.graph ||= g rescue nil
        e
      end
      yield path
    end
  else
    iter.extend IteratorPathMixin
    iter.graph = graph
    iter
  end
rescue java.util.NoSuchElementException
  self
end

#empty?Boolean

Returns true if this route currently has no elements.



279
280
281
# File 'lib/pacer/core/route.rb', line 279

def empty?
  none?
end

#except(excluded) ⇒ Object



4
5
6
7
8
9
10
# File 'lib/pacer/filter/collection_filter.rb', line 4

def except(excluded)
  if excluded.is_a? Symbol
    chain_route :filter => :property, :block => proc { |v| v.vars[excluded] != v }
  else
    chain_route :filter => :collection, :except => excluded
  end
end

#extensionsSet[extension]

Get the set of extensions currently on this route.



319
320
321
# File 'lib/pacer/core/route.rb', line 319

def extensions
  @extensions ||= Set[]
end

#extensions=(exts) ⇒ Object

Add extensions to this route.

See Also:



312
313
314
315
# File 'lib/pacer/core/route.rb', line 312

def extensions=(exts)
  @extensions ||= Set[]
  add_extensions Set[*exts]
end

#from_graph?(g) ⇒ Boolean

Returns true if the given graph is the one this route operates on.



43
44
45
# File 'lib/pacer/core/route.rb', line 43

def from_graph?(g)
  graph.equals g
end

#inspect(limit = nil) ⇒ String

Returns a string representation of the route definition. If there are less than Graph#inspect_limit matches, it will also output all matching elements formatted in columns up to a maximum character width of Graph#columns. If this output behaviour is undesired, it may be turned off by calling #route on the current route.



235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
# File 'lib/pacer/core/route.rb', line 235

def inspect(limit = nil)
  if Pacer.hide_route_elements or hide_elements or source_iterator.nil?
    "#<#{inspect_strings.join(' -> ')}>"
  else
    Pacer.hide_route_elements do
      count = 0
      limit ||= Pacer.inspect_limit
      results = collect do |v|
        count += 1
        return route.inspect if count > limit
        v.inspect
      end
      if count > 0
        lens = results.collect { |r| r.length }
        max = lens.max
        cols = (Pacer.columns / (max + 1).to_f).floor
        cols = 1 if cols < 1
        template_part = ["%-#{max}s"]
        template = (template_part * cols).join(' ')
        results.each_slice(cols) do |row|
          template = (template_part * row.count).join(' ') if row.count < cols
          puts template % row
        end
      end
      puts "Total: #{ count }"
      "#<#{inspect_strings.join(' -> ')}>"
    end
  end
end

#only(included) ⇒ Object



16
17
18
19
20
21
22
# File 'lib/pacer/filter/collection_filter.rb', line 16

def only(included)
  if included.is_a? Symbol
    chain_route :filter => :property, :block => proc { |v| v.vars[included] == v }
  else
    chain_route :filter => :collection, :only => included
  end
end

#root?Boolean

Return true if this route is at the beginning of the route definition.



67
68
69
# File 'lib/pacer/core/route.rb', line 67

def root?
  !@source.nil? or @back.nil?
end

#routeself

TODO:

rename this method

Prevents the route from being evaluated when it is inspected. Useful for computationally expensive or one-time routes.



77
78
79
80
# File 'lib/pacer/core/route.rb', line 77

def route
  @hide_elements = true
  self
end

#set_pipe_source(src) ⇒ Object

Note:

all routes derived from any route in the chain will be affected so use with caution.

Change the source of this route.



341
342
343
344
345
346
347
# File 'lib/pacer/core/route.rb', line 341

def set_pipe_source(src)
  if @back
    @back.set_pipe_source src
  else
    self.source = src
  end
end

#varsHash

TODO:

It would maybe be better if the vars were tied to the thread context or preferably to the actual pipe instance in use. The current implementation of vars is not threadsafe if the same route is being used in multiple threads concurrently.

Returns the hash of variables used during the previous evaluation of the route.

The contents of vars is expected to be in a state relevant to the latest route being evaluated and is primarily meant for internal use, but YMMV.



95
96
97
98
99
100
101
# File 'lib/pacer/core/route.rb', line 95

def vars
  if @back
    @back.vars
  else
    @vars ||= {}
  end
end