pacer-jogger 0.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.document +5 -0
- data/Gemfile +9 -0
- data/Gemfile.lock +34 -0
- data/LICENSE.txt +20 -0
- data/README.markdown +90 -0
- data/Rakefile +55 -0
- data/VERSION +1 -0
- data/lib/jogger.rb +80 -0
- data/pacer-jogger.gemspec +62 -0
- data/spec/lib/jogger_spec.rb +58 -0
- data/spec/spec_helper.rb +7 -0
- metadata +117 -0
data/.document
ADDED
data/Gemfile
ADDED
data/Gemfile.lock
ADDED
@@ -0,0 +1,34 @@
|
|
1
|
+
GEM
|
2
|
+
remote: http://rubygems.org/
|
3
|
+
specs:
|
4
|
+
diff-lcs (1.1.3)
|
5
|
+
git (1.2.5)
|
6
|
+
jeweler (1.7.0)
|
7
|
+
bundler (~> 1.0)
|
8
|
+
git (>= 1.2.5)
|
9
|
+
rake
|
10
|
+
rdoc
|
11
|
+
json (1.6.5)
|
12
|
+
rake (0.9.2.2)
|
13
|
+
rdoc (3.12)
|
14
|
+
json (~> 1.4)
|
15
|
+
rspec (2.8.0)
|
16
|
+
rspec-core (~> 2.8.0)
|
17
|
+
rspec-expectations (~> 2.8.0)
|
18
|
+
rspec-mocks (~> 2.8.0)
|
19
|
+
rspec-core (2.8.0)
|
20
|
+
rspec-expectations (2.8.0)
|
21
|
+
diff-lcs (~> 1.1.2)
|
22
|
+
rspec-mocks (2.8.0)
|
23
|
+
shoulda (2.11.3)
|
24
|
+
yard (0.7.4)
|
25
|
+
|
26
|
+
PLATFORMS
|
27
|
+
ruby
|
28
|
+
|
29
|
+
DEPENDENCIES
|
30
|
+
bundler (~> 1.0.0)
|
31
|
+
jeweler (~> 1.7.0)
|
32
|
+
rspec
|
33
|
+
shoulda
|
34
|
+
yard
|
data/LICENSE.txt
ADDED
@@ -0,0 +1,20 @@
|
|
1
|
+
Copyright (c) 2012 Jannis Hermanns
|
2
|
+
|
3
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
4
|
+
a copy of this software and associated documentation files (the
|
5
|
+
"Software"), to deal in the Software without restriction, including
|
6
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
7
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
8
|
+
permit persons to whom the Software is furnished to do so, subject to
|
9
|
+
the following conditions:
|
10
|
+
|
11
|
+
The above copyright notice and this permission notice shall be
|
12
|
+
included in all copies or substantial portions of the Software.
|
13
|
+
|
14
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
15
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
16
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
17
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
18
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
19
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
20
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.markdown
ADDED
@@ -0,0 +1,90 @@
|
|
1
|
+
# Jogger
|
2
|
+
|
3
|
+
Jogger is a JRuby library that enables lazy people to do very expressive graph traversals with the great [pacer gem](https://github.com/pangloss/pacer). If you don't know what the pacer gem is, you should probably not be here and check pacer out first.
|
4
|
+
|
5
|
+
# What does it do?
|
6
|
+
|
7
|
+
Jogger does two things:
|
8
|
+
|
9
|
+
1. Keep the current pacer traversal in an instance variable and allow for method chaining as well as changing the internal state of the traversal
|
10
|
+
2. Allows you to group together parts of a traversal (single pipes or groups of them) and give them a name. Named traversals. Helps to stay DRY.
|
11
|
+
|
12
|
+
The former is really just a syntax thing, whereas the latter can help you a great deal modeling semantics of your business logic as parts of traversals. These sentences confuse me, so I will give you examples.
|
13
|
+
|
14
|
+
# Example time!
|
15
|
+
|
16
|
+
## 1. Keep track of the current traversal
|
17
|
+
|
18
|
+
To demonstrate why point 1) in the list above can be useful, look at this traversal. It helps me find out what movies my female friends like the most, so I can impress them in a conversation:
|
19
|
+
|
20
|
+
t = my_pacer_vertex.in(:friends)
|
21
|
+
t = t.filter{ |v| v.properties['gender'] == 'female}
|
22
|
+
t = t.out(:likes)
|
23
|
+
t = t.filter{ |v| v.properties['type'] == 'Movie' }
|
24
|
+
t = t.group_count{ |v| v }
|
25
|
+
t = t.sort_by{ |v, c| -c }
|
26
|
+
|
27
|
+
Since I'm a very lazy person, I would prefer to write it a little shorter. Especially, since these multi step traversals are a pattern I found in our code at [moviepilot.com](http://moviepilot.com)) a lot.
|
28
|
+
|
29
|
+
So here's the Jogger way of expressing the same traversal:
|
30
|
+
|
31
|
+
t = Jogger.new(my_pacer_vertex)
|
32
|
+
t.in(:friends)
|
33
|
+
t.filter{ |v| v.properties['gender'] == 'female' }
|
34
|
+
t.out(:likes)
|
35
|
+
t.filter{ |v| v.properties['type'] == 'Movie' }
|
36
|
+
t.group_count{ |v| v }
|
37
|
+
t.sort_by{ |v, c| -c }
|
38
|
+
|
39
|
+
See what I did there? Jogger keeps the current pacer traversal and forwards all method calls to that traversal, and then returns itself. So you could also write (in jogger as well as pacer):
|
40
|
+
|
41
|
+
Jogger.new(my_pacer_node).in(:friends).filter{ … }.out(:likes).group_count{…}
|
42
|
+
|
43
|
+
Just saying, you can chain your methods, but I don't like it because I can only focus on 72 characters per line at max. If you want to access the current traversal, just call `result` on your Jogger instance.
|
44
|
+
|
45
|
+
## 2. Named traversals
|
46
|
+
|
47
|
+
So that traversal above, traversing from a node to all its friends, is pretty simple, but it could be simpler. Especially if it does things that you want to reuse in many other places. If you would explain the traveral to somebody, you'd say something along the lines of "The most popular movies amongst my friends, but only girls". How cool would it be if I just had to write this:
|
48
|
+
|
49
|
+
t = Jogger.new(my_pacer_vertex)
|
50
|
+
t.friends(:female)
|
51
|
+
t.top_list(:movies)
|
52
|
+
|
53
|
+
No problem. Just define a few named traversals that do exactly this.
|
54
|
+
|
55
|
+
class Jogger
|
56
|
+
module NamedTraversals
|
57
|
+
|
58
|
+
# Traverse to somebody's woman friends
|
59
|
+
def self.friends(current_traversal, gender)
|
60
|
+
t = current_traversal.in(:friends)
|
61
|
+
t = t.filter{|v| v.properties['gender'] == gender}
|
62
|
+
end
|
63
|
+
|
64
|
+
# Group and sort
|
65
|
+
def self.top_list(current_traversal, type)
|
66
|
+
t = current_traversal.out(type)
|
67
|
+
t = t.filter{ |v| v.properties['type'] == 'Movie' }
|
68
|
+
t = t.group_count{ |v| v }
|
69
|
+
t = t.sort_by{ |v, c| -c }
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
These are silly examples, but if you look at your traversals I guarantee that you will find repeated patterns all over the place, and Jogger can help you stop repeating these and making the actual traversals much easier on the eyes.
|
75
|
+
|
76
|
+
# Installation
|
77
|
+
|
78
|
+
First, you need to load pacer and whatever graph db connector you need (we use pacer-neo4j, by the way) and define your named traversals as above. Jogger doesn't include these on purpose. Then, you have to:
|
79
|
+
|
80
|
+
gem install pacer-jogger
|
81
|
+
|
82
|
+
and
|
83
|
+
|
84
|
+
require 'jogger'
|
85
|
+
|
86
|
+
or if you're using bundler, add this to your Gemfile and bundle:
|
87
|
+
|
88
|
+
gem "pacer-jogger", :require => "jogger"
|
89
|
+
|
90
|
+
That's it!
|
data/Rakefile
ADDED
@@ -0,0 +1,55 @@
|
|
1
|
+
# encoding: utf-8
|
2
|
+
|
3
|
+
require 'rubygems'
|
4
|
+
require 'bundler'
|
5
|
+
begin
|
6
|
+
Bundler.setup(:default, :development)
|
7
|
+
rescue Bundler::BundlerError => e
|
8
|
+
$stderr.puts e.message
|
9
|
+
$stderr.puts "Run `bundle install` to install missing gems"
|
10
|
+
exit e.status_code
|
11
|
+
end
|
12
|
+
require 'rake'
|
13
|
+
require 'yard'
|
14
|
+
require 'rspec/core/rake_task'
|
15
|
+
|
16
|
+
require 'jeweler'
|
17
|
+
Jeweler::Tasks.new do |gem|
|
18
|
+
gem.name = "pacer-jogger"
|
19
|
+
gem.homepage = "http://github.com/jayniz/jogger"
|
20
|
+
gem.license = "MIT"
|
21
|
+
gem.summary = %Q{Pacer traversals for lazy people}
|
22
|
+
gem.description = %Q{Allows to group traversal fragments/pipes to named traversals and call them like they were pacer pipes.}
|
23
|
+
gem.email = "jannis@gmail.com"
|
24
|
+
gem.authors = ["Jannis Hermanns"]
|
25
|
+
# dependencies defined in Gemfile
|
26
|
+
end
|
27
|
+
Jeweler::RubygemsDotOrgTasks.new
|
28
|
+
|
29
|
+
require 'rake/testtask'
|
30
|
+
Rake::TestTask.new(:test) do |test|
|
31
|
+
test.libs << 'lib' << 'test'
|
32
|
+
test.pattern = 'test/**/test_*.rb'
|
33
|
+
test.verbose = true
|
34
|
+
end
|
35
|
+
|
36
|
+
#
|
37
|
+
# RSpec
|
38
|
+
#
|
39
|
+
task :default => [:spec]
|
40
|
+
task :test => [:spec]
|
41
|
+
desc "run spec tests"
|
42
|
+
RSpec::Core::RakeTask.new('spec') do |t|
|
43
|
+
t.pattern = 'spec/**/*_spec.rb'
|
44
|
+
end
|
45
|
+
|
46
|
+
|
47
|
+
#
|
48
|
+
# Yard
|
49
|
+
#
|
50
|
+
desc 'Generate documentation'
|
51
|
+
YARD::Rake::YardocTask.new do |t|
|
52
|
+
t.files = ['lib/**/*.rb', '-', 'LICENSE']
|
53
|
+
t.options = ['--main', 'README.md', '--no-private']
|
54
|
+
end
|
55
|
+
|
data/VERSION
ADDED
@@ -0,0 +1 @@
|
|
1
|
+
0.0.1
|
data/lib/jogger.rb
ADDED
@@ -0,0 +1,80 @@
|
|
1
|
+
|
2
|
+
# Allows to formulate traversals by using predefined
|
3
|
+
# named traversals. Also allows for method chaining.
|
4
|
+
#
|
5
|
+
# All named traversals are defined in {PacerTraversal::NamedTraversals}
|
6
|
+
# and new ones can be added using {Jogger.add_traversal}.
|
7
|
+
#
|
8
|
+
# Instances have a @current_traversal variable that is
|
9
|
+
# updated with each chained call of {#traverse}.
|
10
|
+
#
|
11
|
+
# Beware, it also uses method missing to delegate unknown methods to
|
12
|
+
# the current traversal. So after you're done chaining things, you can
|
13
|
+
# do more stuff with it after you're done, e.g. call count on it:
|
14
|
+
#
|
15
|
+
# t = Jogger.new(some_node)
|
16
|
+
# t.traverse(:some).traverse(:where).count
|
17
|
+
#
|
18
|
+
# So everything except for {#traverse} is called on the
|
19
|
+
# @current_traversal
|
20
|
+
class Jogger
|
21
|
+
|
22
|
+
|
23
|
+
# @param initial_node [Object] A node to start out with. Can also be
|
24
|
+
# the result of a prior traversal you did outside of this class
|
25
|
+
def initialize(initial_node = nil)
|
26
|
+
@current_traversal = initial_node
|
27
|
+
end
|
28
|
+
|
29
|
+
# @return [Hash] The current state of the traversal as returned by pacer
|
30
|
+
def result
|
31
|
+
@current_traversal
|
32
|
+
end
|
33
|
+
|
34
|
+
# Runs the traversal with the same name as the called method on the
|
35
|
+
# current traversal and replaces the current traversal (== the state)
|
36
|
+
# with the results of the named traversal.
|
37
|
+
#
|
38
|
+
# If you call a method that is not a named traversal, the method call
|
39
|
+
# is delegated to the @current traversal. Still, this will return self.
|
40
|
+
# This is useful for more traversals after named routes.
|
41
|
+
#
|
42
|
+
# @return [Jogger] Returns itself so you can chain multiple
|
43
|
+
# {#traverse} calls
|
44
|
+
def method_missing(method, *args, &block)
|
45
|
+
begin
|
46
|
+
traversal_args = [method, args].flatten.compact
|
47
|
+
@current_traversal = Jogger.traverse(@current_traversal, *traversal_args)
|
48
|
+
rescue ArgumentError
|
49
|
+
begin
|
50
|
+
@current_traversal = @current_traversal.send(method, *args, &block)
|
51
|
+
rescue NoMethodError
|
52
|
+
raise "Unknown traversal #{method}"
|
53
|
+
end
|
54
|
+
end
|
55
|
+
self
|
56
|
+
end
|
57
|
+
|
58
|
+
# Runs a named traversal on a given traversal. For example, you
|
59
|
+
# could give it a start node as traversal base and a traversal named
|
60
|
+
# :go_to_all_subscribers to go to all subscribers from that node.
|
61
|
+
#
|
62
|
+
# @param traversal_base [Object] The result of a previous traversal
|
63
|
+
# or a pacer node you want to begin your traversal with
|
64
|
+
# @param named_traversal [Symbol] The name of the predefined traversal
|
65
|
+
# you want to run on the traversal_base
|
66
|
+
# @param opts [Object] Whatever you want to pass to the named traverser
|
67
|
+
# @return [Object] The result of the traversal.
|
68
|
+
def self.traverse(traversal_base, named_traversal, opts = nil)
|
69
|
+
raise ArgumentError, "Unknown traversal #{named_traversal}" unless valid_traversal?(named_traversal)
|
70
|
+
args = [named_traversal, traversal_base] + [opts].compact
|
71
|
+
Jogger::NamedTraversals.send(*args)
|
72
|
+
end
|
73
|
+
|
74
|
+
private
|
75
|
+
|
76
|
+
def self.valid_traversal?(traversal)
|
77
|
+
Jogger::NamedTraversals.respond_to? traversal
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
@@ -0,0 +1,62 @@
|
|
1
|
+
# Generated by jeweler
|
2
|
+
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run 'rake gemspec'
|
4
|
+
# -*- encoding: utf-8 -*-
|
5
|
+
|
6
|
+
Gem::Specification.new do |s|
|
7
|
+
s.name = "pacer-jogger"
|
8
|
+
s.version = "0.0.1"
|
9
|
+
|
10
|
+
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
|
+
s.authors = ["Jannis Hermanns"]
|
12
|
+
s.date = "2012-01-23"
|
13
|
+
s.description = "Allows to group traversal fragments/pipes to named traversals and call them like they were pacer pipes."
|
14
|
+
s.email = "jannis@gmail.com"
|
15
|
+
s.extra_rdoc_files = [
|
16
|
+
"LICENSE.txt",
|
17
|
+
"README.markdown"
|
18
|
+
]
|
19
|
+
s.files = [
|
20
|
+
".document",
|
21
|
+
"Gemfile",
|
22
|
+
"Gemfile.lock",
|
23
|
+
"LICENSE.txt",
|
24
|
+
"README.markdown",
|
25
|
+
"Rakefile",
|
26
|
+
"VERSION",
|
27
|
+
"lib/jogger.rb",
|
28
|
+
"pacer-jogger.gemspec",
|
29
|
+
"spec/lib/jogger_spec.rb",
|
30
|
+
"spec/spec_helper.rb"
|
31
|
+
]
|
32
|
+
s.homepage = "http://github.com/jayniz/jogger"
|
33
|
+
s.licenses = ["MIT"]
|
34
|
+
s.require_paths = ["lib"]
|
35
|
+
s.rubygems_version = "1.8.10"
|
36
|
+
s.summary = "Pacer traversals for lazy people"
|
37
|
+
|
38
|
+
if s.respond_to? :specification_version then
|
39
|
+
s.specification_version = 3
|
40
|
+
|
41
|
+
if Gem::Version.new(Gem::VERSION) >= Gem::Version.new('1.2.0') then
|
42
|
+
s.add_development_dependency(%q<shoulda>, [">= 0"])
|
43
|
+
s.add_development_dependency(%q<bundler>, ["~> 1.0.0"])
|
44
|
+
s.add_development_dependency(%q<jeweler>, ["~> 1.7.0"])
|
45
|
+
s.add_development_dependency(%q<rspec>, [">= 0"])
|
46
|
+
s.add_development_dependency(%q<yard>, [">= 0"])
|
47
|
+
else
|
48
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
49
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
50
|
+
s.add_dependency(%q<jeweler>, ["~> 1.7.0"])
|
51
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
52
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
53
|
+
end
|
54
|
+
else
|
55
|
+
s.add_dependency(%q<shoulda>, [">= 0"])
|
56
|
+
s.add_dependency(%q<bundler>, ["~> 1.0.0"])
|
57
|
+
s.add_dependency(%q<jeweler>, ["~> 1.7.0"])
|
58
|
+
s.add_dependency(%q<rspec>, [">= 0"])
|
59
|
+
s.add_dependency(%q<yard>, [">= 0"])
|
60
|
+
end
|
61
|
+
end
|
62
|
+
|
@@ -0,0 +1,58 @@
|
|
1
|
+
require_relative '../spec_helper'
|
2
|
+
|
3
|
+
class MyFakedPacerResult
|
4
|
+
def some_existing_pacer_method
|
5
|
+
:is_there
|
6
|
+
end
|
7
|
+
end
|
8
|
+
|
9
|
+
class Jogger
|
10
|
+
module NamedTraversals
|
11
|
+
# This just multiplies the current traversal with x.
|
12
|
+
# In a real use case you would take the current traversal,
|
13
|
+
# traverse some more, and yield the result of your traversal.
|
14
|
+
def self.test_traverser(current_traversal, x)
|
15
|
+
(current_traversal || 1) * x
|
16
|
+
end
|
17
|
+
|
18
|
+
def self.no_argument_traverser(current_traversal)
|
19
|
+
:worked
|
20
|
+
end
|
21
|
+
|
22
|
+
def self.method_missing_dummy(current_traversal)
|
23
|
+
MyFakedPacerResult.new
|
24
|
+
end
|
25
|
+
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
describe Jogger do
|
30
|
+
|
31
|
+
|
32
|
+
it "runs the named proc and replaces the current traversal with its result" do
|
33
|
+
p = Jogger.new
|
34
|
+
p.test_traverser(2)
|
35
|
+
p.result.should == 2
|
36
|
+
end
|
37
|
+
|
38
|
+
it "allows for method chaining" do
|
39
|
+
p = Jogger.new
|
40
|
+
p.test_traverser(2).test_traverser(3)
|
41
|
+
p.result.should == 6
|
42
|
+
end
|
43
|
+
|
44
|
+
it "doesn't allow to run a non existant traversal" do
|
45
|
+
lambda do
|
46
|
+
p = Jogger.new
|
47
|
+
p.this_does_not_exist
|
48
|
+
end.should raise_error("Unknown traversal this_does_not_exist")
|
49
|
+
end
|
50
|
+
|
51
|
+
it "works for traversals without arguments" do
|
52
|
+
Jogger.new.no_argument_traverser.result.should == :worked
|
53
|
+
end
|
54
|
+
|
55
|
+
it "delegates method calls to the current traversal" do
|
56
|
+
Jogger.new.method_missing_dummy.some_existing_pacer_method.result.should == :is_there
|
57
|
+
end
|
58
|
+
end
|
data/spec/spec_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,117 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: pacer-jogger
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.0.1
|
5
|
+
prerelease:
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Jannis Hermanns
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
date: 2012-01-23 00:00:00.000000000Z
|
13
|
+
dependencies:
|
14
|
+
- !ruby/object:Gem::Dependency
|
15
|
+
name: shoulda
|
16
|
+
requirement: &70246624766620 !ruby/object:Gem::Requirement
|
17
|
+
none: false
|
18
|
+
requirements:
|
19
|
+
- - ! '>='
|
20
|
+
- !ruby/object:Gem::Version
|
21
|
+
version: '0'
|
22
|
+
type: :development
|
23
|
+
prerelease: false
|
24
|
+
version_requirements: *70246624766620
|
25
|
+
- !ruby/object:Gem::Dependency
|
26
|
+
name: bundler
|
27
|
+
requirement: &70246624765680 !ruby/object:Gem::Requirement
|
28
|
+
none: false
|
29
|
+
requirements:
|
30
|
+
- - ~>
|
31
|
+
- !ruby/object:Gem::Version
|
32
|
+
version: 1.0.0
|
33
|
+
type: :development
|
34
|
+
prerelease: false
|
35
|
+
version_requirements: *70246624765680
|
36
|
+
- !ruby/object:Gem::Dependency
|
37
|
+
name: jeweler
|
38
|
+
requirement: &70246624765080 !ruby/object:Gem::Requirement
|
39
|
+
none: false
|
40
|
+
requirements:
|
41
|
+
- - ~>
|
42
|
+
- !ruby/object:Gem::Version
|
43
|
+
version: 1.7.0
|
44
|
+
type: :development
|
45
|
+
prerelease: false
|
46
|
+
version_requirements: *70246624765080
|
47
|
+
- !ruby/object:Gem::Dependency
|
48
|
+
name: rspec
|
49
|
+
requirement: &70246624764500 !ruby/object:Gem::Requirement
|
50
|
+
none: false
|
51
|
+
requirements:
|
52
|
+
- - ! '>='
|
53
|
+
- !ruby/object:Gem::Version
|
54
|
+
version: '0'
|
55
|
+
type: :development
|
56
|
+
prerelease: false
|
57
|
+
version_requirements: *70246624764500
|
58
|
+
- !ruby/object:Gem::Dependency
|
59
|
+
name: yard
|
60
|
+
requirement: &70246624763920 !ruby/object:Gem::Requirement
|
61
|
+
none: false
|
62
|
+
requirements:
|
63
|
+
- - ! '>='
|
64
|
+
- !ruby/object:Gem::Version
|
65
|
+
version: '0'
|
66
|
+
type: :development
|
67
|
+
prerelease: false
|
68
|
+
version_requirements: *70246624763920
|
69
|
+
description: Allows to group traversal fragments/pipes to named traversals and call
|
70
|
+
them like they were pacer pipes.
|
71
|
+
email: jannis@gmail.com
|
72
|
+
executables: []
|
73
|
+
extensions: []
|
74
|
+
extra_rdoc_files:
|
75
|
+
- LICENSE.txt
|
76
|
+
- README.markdown
|
77
|
+
files:
|
78
|
+
- .document
|
79
|
+
- Gemfile
|
80
|
+
- Gemfile.lock
|
81
|
+
- LICENSE.txt
|
82
|
+
- README.markdown
|
83
|
+
- Rakefile
|
84
|
+
- VERSION
|
85
|
+
- lib/jogger.rb
|
86
|
+
- pacer-jogger.gemspec
|
87
|
+
- spec/lib/jogger_spec.rb
|
88
|
+
- spec/spec_helper.rb
|
89
|
+
homepage: http://github.com/jayniz/jogger
|
90
|
+
licenses:
|
91
|
+
- MIT
|
92
|
+
post_install_message:
|
93
|
+
rdoc_options: []
|
94
|
+
require_paths:
|
95
|
+
- lib
|
96
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
97
|
+
none: false
|
98
|
+
requirements:
|
99
|
+
- - ! '>='
|
100
|
+
- !ruby/object:Gem::Version
|
101
|
+
version: '0'
|
102
|
+
segments:
|
103
|
+
- 0
|
104
|
+
hash: -4043812696808555855
|
105
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
106
|
+
none: false
|
107
|
+
requirements:
|
108
|
+
- - ! '>='
|
109
|
+
- !ruby/object:Gem::Version
|
110
|
+
version: '0'
|
111
|
+
requirements: []
|
112
|
+
rubyforge_project:
|
113
|
+
rubygems_version: 1.8.10
|
114
|
+
signing_key:
|
115
|
+
specification_version: 3
|
116
|
+
summary: Pacer traversals for lazy people
|
117
|
+
test_files: []
|