Let's see an example of how we might extend a simple graph containing airports (vertices) and flights (edges).
You can paste the code examples below directly in the IRB, or save them in a file, and call load(path_to_file)
.
Create some data
In order to use our extension, let's create a simple test graph:
require 'pacer'
# Create an in-memory TinkerGraph
g = Pacer.tg()
g.transaction do # optional with TinkerGraph
lax = g.create_vertex({airport: 'LAX', city: 'Los Angeles'})
lga = g.create_vertex({airport: 'LGA', city: 'New York'})
sfo = g.create_vertex({airport: 'SFO', city: 'San Francisco'})
yyz = g.create_vertex({airport: 'YYZ', city: 'Toronto'})
lga.add_edges_to(:flight, lax, {airline: 'Delta'})
lga.add_edges_to(:flight, yyz, {airline: 'Air Canada'})
yyz.add_edges_to(:flight, lga, {airline: 'Air Canada'})
lax.add_edges_to(:flight, yyz, {airline: 'Delta'})
lax.add_edges_to(:flight, sfo, {airline: 'WestJet'})
lax.add_edges_to(:flight, sfo, {airline: 'American Airlines'})
end
Create an extension
module Airport
module Vertex
def short_description
"#{self[:airport]} airport, #{self[:city]}"
end
end
module Route
def departures
self.out_e(:flight)
end
def arrivals
self.in_e(:flight)
end
end
end
A note on vertices vs. routes
In Pacer, a single vertex can easily be wrapped in a route (containing a single element).
Therefore,
- A single vertex gets extended by both
Vertex
and Route
methods.
- A route of vertices is extended only by both
Route
methods.
Tip: If a method makes sense for both, a single item and a collection, define it as a Route method.
If it only makes sense for a single item, define it as a Vertex method.
Use the extension
At this point, we can extend routes and vertices with the Airport
extension.
# The Airport module/extension
jruby-1.7.19 :112 > Airport
=> Airport
# Extending a vertex route with the Airport extension
jruby-1.7.19 :113 > airports = g.v(Airport)
#<V[3]> #<V[2]> #<V[1]> #<V[0]>
Total: 4
# Getting a single vertex out of the extended route
jruby-1.7.19 :114 > airport = airports.first
Notice that a route gets extended with the departures
and arrivals
methods, and a single vertex gets extended with departures
, arrivals
and short_description
.
# Calling the arrivals method on a route
jruby-1.7.19 :116 > airports.arrivals
#<E[7]:0-flight-3> #<E[5]:1-flight-3> #<E[9]:0-flight-2> #<E[8]:0-flight-2> #<E[6]:3-flight-1> #<E[4]:1-flight-0>
Total: 6
# Calling the departures method on a vertex
jruby-1.7.19 :117 > airport.departures
#<E[6]:3-flight-1>
Total: 1
# Calling pretty print on a vertex
jruby-1.7.19 :118 > airport.short_description
=> "YYZ airport, Toronto"
# Trying to call short_description on a route will result in an error
jruby-1.7.19 :119 > airports.short_description
NoMethodError
The display_name
method
The display_name
is a special vertex method - If it is defined, Pacer will use it to print items to the console.
For example, in our Airport
extension, let change the name of the short_description
method to be display_name
:
module Airport
module Vertex
def display_name
"#{self[:airport]} airport, #{self[:city]}"
end
end
module Route
def departures
self.out_e(:flight)
end
def arrivals
self.in_e(:flight)
end
end
end
Now, when we run queries in the IRB, their output will look like this:
jruby-1.7.19 :171 > g.v(Airport)
#<V[3] YYZ airport, Toronto> #<V[2] SFO airport, San Francisco> #<V[1] LGA airport, New York> #<V[0] LAX airport, Los Angeles>
Total: 4