Class: Pacer::Route

Inherits:
Object
  • Object
show all
Includes:
Core::Route, Pacer::Routes::RouteOperations
Defined in:
lib/pacer/route.rb,
lib/pacer/filter/empty_filter.rb,
lib/pacer/filter/property_filter.rb

Overview

The base class for almost everything in Pacer. Every route is an instance of this class with a variety of modules mixed into the instance at runtime.

The class definition only contains methods directly related to the construction of new Routes. For methods more likely to be used, see the Core::Route module which is always mixed into this class.

See Also:

Instance Attribute Summary collapse

Attributes included from Core::Route

#hide_elements, #lookahead_replacement, #pipe_args, #pipe_class, #remove_from_lookahead, #route_name

Class Method Summary collapse

Instance Method Summary collapse

Methods included from Pacer::Routes::RouteOperations

#aggregate, #all, #as, #as_var, #at, #breadth_first, #compact, #count, #count_section, #counted, #custom_sort_section, #deepest, #difference_sections, #edges_route?, #fast_group_count, #flat_map, #frequency_counts, #frequency_groups, #gather_section, #group_count, #has?, #has_count?, #has_count_route, #identity, #inspect_class_name, #intersect_sections, #is, #is_not, #is_unique, #java_loop, #join, #left_difference_sections, #limit, #limit_section, #lookahead, #lookup_ids, #loop, #make_pairs, #map, #mixed_route?, #most_frequent, #neg_lookahead, #offset, #pages, #parallel, #process, #range, #reducer, #reject, #repeat, #right_difference_sections, #section, #select, #sort_section, #stream_sort, #stream_uniq, #uniq, #uniq_in_section, #unique?, #unique_path, #unjoin, #unless, #vertices_route?, #visitor, #where

Methods included from Pacer::Routes::BulkOperations

#bulk_job, #bulk_map

Methods included from Core::Route

#-, #==, #add_extensions, #branch, #chain_route, #cond, #description, #detach, #each, #empty?, #except, #from_graph?, #gather, #graph, #help, #inspect, #no_extensions, #only, #paths, #pipe, #random, #root?, #route, #scatter, #set_extensions, #set_pipe_source, #set_wrapper, #vars

Constructor Details

#initialize(source, config, args) ⇒ Route

Create a new route. It should be very rare that you would need to directly create a Route object.

See Core::Graph::GraphRoute and PacerGraph for methods to build routes based on a graph.

See ElementWrapper, VertexWrapper and EdgeWrapper for methods to build routes based on an individual graph element.

See Pacer’s Enumerable#to_route method to create a route based on an Array, a Set or any other Enumerable type.

All other keys sent to the args method will be converted into setter method calls and called against the instantiated route to allow modules to define their own setup however they need.

When the route object is fully initialized, the #after_initialize method is called to allow mixins to do any additional setup.

Examples:

If a route is constructed with the a custom key:

route = Route.new(:filter => :block, :block => proc { |element| element.element_id.even? })

# is theoretically the same as

route = Route.new
route.extend Pacer::Filter::BlockFilter
route.block = proc { |element| element.element_id.even? }
route

Parameters:

Options Hash (args):

  • :graph (Graph)

    the graph this route is based on

  • :back (Route)

    the previous route in the chain

  • :element_type (element type)
  • :modules (Module)

    additional modules to mix in

  • :filter (Symbol, Module)

    the filter to use as this route’s function

  • :side_effect (Symbol, Module)

    the side effect to use as this route’s function (Also triggers the Core::SideEffect mixin)

  • :transform (Symbol, Module)

    the transform module to use as this route’s function

  • :extensions ([Module])

    extensions for this route

See Also:



133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
# File 'lib/pacer/route.rb', line 133

def initialize(source, config, args)
  if source.is_a? Route
    @back = source
  else
    @pacer_source = source
  end
  @config = config
  @args = args

  args.each do |key, value|
    send("#{key}=", value)
  end

  after_initialize
rescue Exception => e
  begin
    if Pacer.verbose?
      puts "Exception #{ e.class } #{ e.message } ..."
      puts "... creating #{ config.inspect } route"
      puts "... with #{ args.inspect }"
    end
  rescue Exception
  end
  raise e
end

Instance Attribute Details

#backObject (readonly)

The previous route in the chain



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

def back
  @back
end

#configObject (readonly)

Returns the value of attribute config.



33
34
35
# File 'lib/pacer/route.rb', line 33

def config
  @config
end

#infoObject

Additional info to include after the class name when generating a name for this route.



74
75
76
# File 'lib/pacer/route.rb', line 74

def info
  @info
end

#pacer_sourceObject (readonly)

The soure of data for the entire chain. Routes that have a source generally should not have a #back



81
82
83
# File 'lib/pacer/route.rb', line 81

def pacer_source
  @pacer_source
end

Class Method Details

.block_branch(back, block, branch_start = nil) ⇒ Object



19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'lib/pacer/filter/empty_filter.rb', line 19

def block_branch(back, block, branch_start = nil)
  if block.arity == 0
    route = block.call rescue nil
  else
    unless branch_start
      if back.is_a? Pacer::Graph
        branch_start = back
      else
        branch_start = Pacer::Route.empty(back)
      end
    end
    route = block.call(branch_start) rescue nil
  end
  if route == branch_start
    identity_branch(back).route
  elsif route.is_a? Pacer::Route
    route.route
  else
    empty(back).map(&block).route
  end
end

.chain_args(filters) ⇒ Object



47
48
49
50
51
52
53
# File 'lib/pacer/filter/property_filter.rb', line 47

def chain_args(filters)
  if filters.wrapper or (filters.extensions and not filters.extensions.empty?)
    { extensions: filters.extensions, wrapper: filters.wrapper }
  else
    {}
  end
end

.edge_filters(graph, filters) ⇒ Object



17
18
19
20
21
22
23
24
25
# File 'lib/pacer/filter/property_filter.rb', line 17

def edge_filters(graph, filters)
  if filters? filters
    filters
  elsif filters? filters.first
    filters.first
  else
    Pacer::Filter::PropertyFilter::EdgeFilters.new(graph, filters)
  end
end

.empty(back) ⇒ Route

This method is useful for creating sideline routes that branch off of the current route.

It creates a new route without any source based on the type, filters, function and extensions of the given route. The main thing about the returned route is that the pipeline that is built from it will not include any of the pipes that make up the route it’s based on.

Parameters:

  • back (Route)

    the route the new route is based on.

Returns:



15
16
17
# File 'lib/pacer/filter/empty_filter.rb', line 15

def empty(back)
  back.chain_route :filter => :empty
end

.filters(graph, filters) ⇒ Object



7
8
9
10
11
12
13
14
15
# File 'lib/pacer/filter/property_filter.rb', line 7

def filters(graph, filters)
  if filters? filters
    filters
  elsif filters? filters.first
    filters.first
  else
    Pacer::Filter::PropertyFilter::Filters.new(graph, filters)
  end
end

.filters?(filters) ⇒ Boolean

Returns:

  • (Boolean)


27
28
29
# File 'lib/pacer/filter/property_filter.rb', line 27

def filters?(filters)
  filters.is_a? Pacer::Filter::PropertyFilter::Filters
end

.identity_branch(back) ⇒ Object



41
42
43
44
# File 'lib/pacer/filter/empty_filter.rb', line 41

def identity_branch(back)
  Pacer::Route.empty(back).chain_route(:pipe_class => Pacer::Pipes::IdentityPipe,
                                       :route_name => '@').route
end

.pipeline(route) ⇒ Pacer::Pipes::BlackboxPipeline

A pipeline is sometimes required if a pipe needs to be passed into a method that will change the starts on the same object that it requests the next result from.

Parameters:

  • route (Route)

    the route to create a pipeline based on

Returns:

  • (Pacer::Pipes::BlackboxPipeline)

    an instantiated pipeline



19
20
21
22
23
24
25
26
27
# File 'lib/pacer/route.rb', line 19

def pipeline(route)
  s, e = route.send(:build_pipeline)
  e = yield e if block_given?
  if s.equal?(e)
    s
  else
    Pacer::Pipes::BlackboxPipeline.new s, e
  end
end

.property_filter(base, args, block, strict = false) ⇒ Object



31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
# File 'lib/pacer/filter/property_filter.rb', line 31

def property_filter(base, args, block, strict = false)
  filters = Pacer::Route.edge_filters(base.graph, args)
  filters.use_lookup! if strict
  filters.blocks = [block] if block
  args = chain_args(filters)
  if filters.extensions_only? and base.is_a? Route
    base.chain_route(args)
  elsif filters.any?
    base.chain_route(args.merge!(filter: :property, filters: filters))
  elsif base.is_a? Pacer::Wrappers::ElementWrapper
    base.chain_route({})
  else
    base
  end
end

Instance Method Details

#element_typeObject

The type of object that this route emits.



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

def element_type
  config[:element_type]
end

#extensionsArray[extension]

Get the set of extensions currently on this route.

The order of extensions for custom defined wrappers are guaranteed. If a wrapper is iterated with additional extensions, a new wrapper will be created dynamically with the original extensions in order followed by any additional extensions in undefined order.

Returns an Array

Returns:

  • (Array[extension])


54
55
56
57
58
59
60
# File 'lib/pacer/route.rb', line 54

def extensions
  if wrapper
    (wrapper.extensions + config[:extensions]).uniq
  else
    config[:extensions]
  end
end

#functionObject

The function mixed into this instance



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

def function
  config[:function]
end

#wrapperObject

The wrapper object to use to wrap elements in.

If it responds to #add_extensions and the rout also has additional extensions, it will be used to generate a new wrapper dynamically.



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

def wrapper
  config[:wrapper]
end