leaderboard 2.0.6 → 2.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/.gitignore +1 -0
- data/CHANGELOG.markdown +6 -1
- data/README.markdown +61 -12
- data/lib/leaderboard.rb +82 -5
- data/lib/leaderboard/version.rb +1 -1
- data/spec/leaderboard_spec.rb +36 -0
- data/spec/spec_helper.rb +1 -1
- data/spec/version_spec.rb +1 -1
- metadata +26 -11
data/.gitignore
CHANGED
data/CHANGELOG.markdown
CHANGED
@@ -1,8 +1,13 @@
|
|
1
1
|
# CHANGELOG
|
2
2
|
|
3
|
+
## leaderboard 2.1.0 (2012-06-11)
|
4
|
+
|
5
|
+
* Added ability to store optional member data alongside the leaderboard data.
|
6
|
+
* `:with_member_data` is now a valid request option when retrieving leader data.
|
7
|
+
|
3
8
|
## leaderboard 2.0.6 (2012-04-26)
|
4
9
|
|
5
|
-
* Added accessor for
|
10
|
+
* Added accessor for `reverse` option so that you can set reverse after creating a leaderboard to see results in either highest-to-lowest or lowest-to-highest order.
|
6
11
|
|
7
12
|
## leaderboard 2.0.5 (2012-03-14)
|
8
13
|
|
data/README.markdown
CHANGED
@@ -19,10 +19,14 @@ check out the Redis documentation, http://redis.io/documentation.
|
|
19
19
|
|
20
20
|
## Compatibility
|
21
21
|
|
22
|
-
The gem has been built and tested under Ruby 1.8.7, Ruby 1.9.2 and Ruby 1.9.3
|
22
|
+
The gem has been built and tested under Ruby 1.8.7, Ruby 1.9.2 and Ruby 1.9.3.
|
23
|
+
|
24
|
+
The gem is compatible with Redis 2.4.x and Redis 2.6.x.
|
23
25
|
|
24
26
|
## Usage
|
25
27
|
|
28
|
+
### Creating a leaderboard
|
29
|
+
|
26
30
|
Create a new leaderboard or attach to an existing leaderboard named 'highscores':
|
27
31
|
|
28
32
|
```ruby
|
@@ -39,6 +43,8 @@ If you need to pass in options for Redis, you can do this in the initializer:
|
|
39
43
|
=> #<Leaderboard:0x00000103095200 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://localhost:6379/1 (Redis v2.2.5)>>
|
40
44
|
```
|
41
45
|
|
46
|
+
### Defining leaderboard options
|
47
|
+
|
42
48
|
The `Leaderboard::DEFAULT_OPTIONS` are as follows:
|
43
49
|
|
44
50
|
```ruby
|
@@ -64,6 +70,18 @@ You can pass in an existing connection to Redis using `:redis_connection` in the
|
|
64
70
|
=> #<Leaderboard:0x000001028791e8 @leaderboard_name="highscores", @page_size=25, @redis_connection=#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>>
|
65
71
|
```
|
66
72
|
|
73
|
+
To use the same connection for multiple leaderboards, reset the options hash before instantiating more leaderboards:
|
74
|
+
|
75
|
+
```ruby
|
76
|
+
redis = Redis.new
|
77
|
+
=> #<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>
|
78
|
+
redis_options = {:redis_connection => redis}
|
79
|
+
=> {:redis_connection=>#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>}
|
80
|
+
highscore_lb = Leaderboard.new('highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
|
81
|
+
redis_options = {:redis_connection => redis}
|
82
|
+
other_highscore_lb = Leaderboard.new('other_highscores', Leaderboard::DEFAULT_OPTIONS, redis_options)
|
83
|
+
```
|
84
|
+
|
67
85
|
You can set the page size to something other than the default page size (25):
|
68
86
|
|
69
87
|
```ruby
|
@@ -72,7 +90,9 @@ You can set the page size to something other than the default page size (25):
|
|
72
90
|
highscore_lb
|
73
91
|
=> #<Leaderboard:0x000001028791e8 @leaderboard_name="highscores", @page_size=5, @redis_connection=#<Redis client v2.2.2 connected to redis://127.0.0.1:6379/0 (Redis v2.2.5)>>
|
74
92
|
```
|
75
|
-
|
93
|
+
|
94
|
+
### Ranking members in the leaderboard
|
95
|
+
|
76
96
|
Add members to your leaderboard using `rank_member`:
|
77
97
|
|
78
98
|
```ruby
|
@@ -92,6 +112,30 @@ Get some information about your leaderboard:
|
|
92
112
|
highscore_lb.total_pages
|
93
113
|
=> 1
|
94
114
|
```
|
115
|
+
|
116
|
+
The `rank_member` call will also accept an optional hash of member data that could
|
117
|
+
be used to store other information about a given member in the leaderboard. This
|
118
|
+
may be useful in situations where you are storing member IDs in the leaderboard and
|
119
|
+
you want to be able to store a member name for display. Example:
|
120
|
+
|
121
|
+
```ruby
|
122
|
+
highscore_lb.rank_member('84849292', 1, {'username' => 'member_name'})
|
123
|
+
```
|
124
|
+
|
125
|
+
You can retrieve, update and remove the optional member data using the
|
126
|
+
`member_data_for`, `update_member_data` and `remove_member_data` calls. Example:
|
127
|
+
|
128
|
+
```ruby
|
129
|
+
highscore_lb.member_data_for('84849292')
|
130
|
+
=> {"username"=>"member_name"}
|
131
|
+
|
132
|
+
highscore_lb.update_member_data('84849292', {'last_updated' => Time.now, 'username' => 'updated_member_name'})
|
133
|
+
=> "OK"
|
134
|
+
highscore_lb.member_data_for('84849292')
|
135
|
+
=> {"username"=>"updated_member_name", "last_updated"=>"2012-06-09 09:11:06 -0400"}
|
136
|
+
|
137
|
+
highscore_lb.remove_member_data('84849292')
|
138
|
+
```
|
95
139
|
|
96
140
|
Get some information about a specific member(s) in the leaderboard:
|
97
141
|
|
@@ -103,7 +147,9 @@ Get some information about a specific member(s) in the leaderboard:
|
|
103
147
|
highscore_lb.rank_for('member_10')
|
104
148
|
=> 1
|
105
149
|
```
|
106
|
-
|
150
|
+
|
151
|
+
### Retrieving members from the leaderboard
|
152
|
+
|
107
153
|
Get page 1 in the leaderboard:
|
108
154
|
|
109
155
|
```ruby
|
@@ -111,8 +157,10 @@ Get page 1 in the leaderboard:
|
|
111
157
|
=> [{:member=>"member_10", :rank=>1, :score=>10.0}, {:member=>"member_9", :rank=>2, :score=>9.0}, {:member=>"member_8", :rank=>3, :score=>8.0}, {:member=>"member_7", :rank=>4, :score=>7.0}, {:member=>"member_6", :rank=>5, :score=>6.0}, {:member=>"member_5", :rank=>6, :score=>5.0}, {:member=>"member_4", :rank=>7, :score=>4.0}, {:member=>"member_3", :rank=>8, :score=>3.0}, {:member=>"member_2", :rank=>9, :score=>2.0}, {:member=>"member_1", :rank=>10, :score=>1.0}]
|
112
158
|
```
|
113
159
|
|
114
|
-
You can pass various options to the calls `leaders`, `around_me` and `ranked_in_list`.
|
115
|
-
|
160
|
+
You can pass various options to the calls `leaders`, `around_me` and `ranked_in_list`.
|
161
|
+
Valid options are `:with_scores`, `:with_rank`, `:with_member_data`, `:use_zero_index_for_rank`
|
162
|
+
and `:page_size`. Below is an example of retrieving the first page in the leaderboard
|
163
|
+
without ranks:
|
116
164
|
|
117
165
|
```ruby
|
118
166
|
highscore_lb.leaders(1, :with_rank => false)
|
@@ -151,6 +199,8 @@ Get rank and score for an arbitrary list of members (e.g. friends) from the lead
|
|
151
199
|
=> [{:member=>"member_1", :rank=>56, :score=>1.0}, {:member=>"member_62", :rank=>34, :score=>62.0}, {:member=>"member_67", :rank=>29, :score=>67.0}]
|
152
200
|
```
|
153
201
|
|
202
|
+
### Ranking multiple members in a leaderboard at once
|
203
|
+
|
154
204
|
Insert multiple data items for members and their associated scores:
|
155
205
|
|
156
206
|
As a splat:
|
@@ -170,7 +220,10 @@ Use this method to do bulk insert of data, but be mindful of the amount of data
|
|
170
220
|
### Other useful methods
|
171
221
|
|
172
222
|
```
|
173
|
-
delete_leaderboard: Delete the current leaderboard
|
223
|
+
delete_leaderboard: Delete the current leaderboard
|
224
|
+
member_data_for(member): Retrieve the optional member data for a given member in the leaderboard
|
225
|
+
update_member_data(member, member_data): Update the optional member data for a given member in the leaderboard
|
226
|
+
remove_member_data(member): Remove the optional member data for a given member in the leaderboard
|
174
227
|
remove_member(member): Remove a member from the leaderboard
|
175
228
|
total_members: Total # of members in the leaderboard
|
176
229
|
total_pages: Total # of pages in the leaderboard given the leaderboard's page_size
|
@@ -189,7 +242,7 @@ Use this method to do bulk insert of data, but be mindful of the amount of data
|
|
189
242
|
```
|
190
243
|
|
191
244
|
Check the [online documentation](http://rubydoc.info/github/agoragames/leaderboard/master/frames) for more detail on each method.
|
192
|
-
|
245
|
+
|
193
246
|
## Performance Metrics
|
194
247
|
|
195
248
|
10 million sequential scores insert:
|
@@ -249,7 +302,7 @@ Average time to request an arbitrary page from the leaderboard:
|
|
249
302
|
=> 0.0014615999999999531
|
250
303
|
```
|
251
304
|
|
252
|
-
Bulk insert performance
|
305
|
+
### Bulk insert performance
|
253
306
|
|
254
307
|
Ranking individual members:
|
255
308
|
|
@@ -278,10 +331,6 @@ end
|
|
278
331
|
=> 22.390000 6.380000 28.770000 ( 31.144027)
|
279
332
|
```
|
280
333
|
|
281
|
-
## Future Ideas
|
282
|
-
|
283
|
-
* Ideas?
|
284
|
-
|
285
334
|
## Ports
|
286
335
|
|
287
336
|
The following ports have been made of the leaderboard gem.
|
data/lib/leaderboard.rb
CHANGED
@@ -29,11 +29,13 @@ class Leaderboard
|
|
29
29
|
# Default options when requesting data from a leaderboard.
|
30
30
|
# +:with_scores+ true: Return scores along with the member names.
|
31
31
|
# +:with_rank+ true: Return ranks along with the member names.
|
32
|
+
# +:with_member_data+ false: Return member data along with the member names.
|
32
33
|
# +:use_zero_index_for_rank+ false: If you want to 0-index ranks.
|
33
34
|
# +:page_size+ nil: The default page size will be used.
|
34
35
|
DEFAULT_LEADERBOARD_REQUEST_OPTIONS = {
|
35
36
|
:with_scores => true,
|
36
37
|
:with_rank => true,
|
38
|
+
:with_member_data => false,
|
37
39
|
:use_zero_index_for_rank => false,
|
38
40
|
:page_size => nil
|
39
41
|
}
|
@@ -108,8 +110,9 @@ class Leaderboard
|
|
108
110
|
#
|
109
111
|
# @param member [String] Member name.
|
110
112
|
# @param score [float] Member score.
|
111
|
-
|
112
|
-
|
113
|
+
# @param member_data [Hash] Optional member data.
|
114
|
+
def rank_member(member, score, member_data = nil)
|
115
|
+
rank_member_in(@leaderboard_name, member, score, member_data)
|
113
116
|
end
|
114
117
|
|
115
118
|
# Rank a member in the named leaderboard.
|
@@ -117,8 +120,65 @@ class Leaderboard
|
|
117
120
|
# @param leaderboard_name [String] Name of the leaderboard.
|
118
121
|
# @param member [String] Member name.
|
119
122
|
# @param score [float] Member score.
|
120
|
-
|
121
|
-
|
123
|
+
# @param member_data [Hash] Optional member data.
|
124
|
+
def rank_member_in(leaderboard_name, member, score, member_data)
|
125
|
+
@redis_connection.multi do |transaction|
|
126
|
+
transaction.zadd(leaderboard_name, score, member)
|
127
|
+
if member_data
|
128
|
+
transaction.hmset(member_data_key(leaderboard_name, member), *member_data.to_a.flatten)
|
129
|
+
end
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
# Retrieve the optional member data for a given member in the leaderboard.
|
134
|
+
#
|
135
|
+
# @param member [String] Member name.
|
136
|
+
#
|
137
|
+
# @return Hash of optional member data.
|
138
|
+
def member_data_for(member)
|
139
|
+
member_data_for_in(@leaderboard_name, member)
|
140
|
+
end
|
141
|
+
|
142
|
+
# Retrieve the optional member data for a given member in the named leaderboard.
|
143
|
+
#
|
144
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
145
|
+
# @param member [String] Member name.
|
146
|
+
#
|
147
|
+
# @return Hash of optional member data.
|
148
|
+
def member_data_for_in(leaderboard_name, member)
|
149
|
+
@redis_connection.hgetall(member_data_key(leaderboard_name, member))
|
150
|
+
end
|
151
|
+
|
152
|
+
# Update the optional member data for a given member in the leaderboard.
|
153
|
+
#
|
154
|
+
# @param member [String] Member name.
|
155
|
+
# @param member_data [Hash] Optional member data.
|
156
|
+
def update_member_data(member, member_data)
|
157
|
+
update_member_data_in(@leaderboard_name, member, member_data)
|
158
|
+
end
|
159
|
+
|
160
|
+
# Update the optional member data for a given member in the named leaderboard.
|
161
|
+
#
|
162
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
163
|
+
# @param member [String] Member name.
|
164
|
+
# @param member_data [Hash] Optional member data.
|
165
|
+
def update_member_data_in(leaderboard_name, member, member_data)
|
166
|
+
@redis_connection.hmset(member_data_key(leaderboard_name, member), *member_data.to_a.flatten)
|
167
|
+
end
|
168
|
+
|
169
|
+
# Remove the optional member data for a given member in the leaderboard.
|
170
|
+
#
|
171
|
+
# @param member [String] Member name.
|
172
|
+
def remove_member_data(member)
|
173
|
+
remove_member_data_in(@leaderboard_name, member)
|
174
|
+
end
|
175
|
+
|
176
|
+
# Remove the optional member data for a given member in the named leaderboard.
|
177
|
+
#
|
178
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
179
|
+
# @param member [String] Member name.
|
180
|
+
def remove_member_data_in(leaderboard_name, member)
|
181
|
+
@redis_connection.del(member_data_key(leaderboard_name, member))
|
122
182
|
end
|
123
183
|
|
124
184
|
# Rank an array of members in the leaderboard.
|
@@ -156,7 +216,10 @@ class Leaderboard
|
|
156
216
|
# @param leaderboard_name [String] Name of the leaderboard.
|
157
217
|
# @param member [String] Member name.
|
158
218
|
def remove_member_from(leaderboard_name, member)
|
159
|
-
@redis_connection.
|
219
|
+
@redis_connection.multi do |transaction|
|
220
|
+
transaction.zrem(leaderboard_name, member)
|
221
|
+
transaction.del(member_data_key(leaderboard_name, member))
|
222
|
+
end
|
160
223
|
end
|
161
224
|
|
162
225
|
# Retrieve the total number of members in the leaderboard.
|
@@ -574,6 +637,10 @@ class Leaderboard
|
|
574
637
|
end
|
575
638
|
end
|
576
639
|
end
|
640
|
+
|
641
|
+
if leaderboard_options[:with_member_data]
|
642
|
+
data[:member_data] = member_data_for_in(leaderboard_name, member)
|
643
|
+
end
|
577
644
|
|
578
645
|
ranks_for_members << data
|
579
646
|
end
|
@@ -601,6 +668,16 @@ class Leaderboard
|
|
601
668
|
|
602
669
|
private
|
603
670
|
|
671
|
+
# Key for retrieving optional member data.
|
672
|
+
#
|
673
|
+
# @param leaderboard_name [String] Name of the leaderboard.
|
674
|
+
# @param member [String] Member name.
|
675
|
+
#
|
676
|
+
# @return a key in the form of +leaderboard_name:data:member+
|
677
|
+
def member_data_key(leaderboard_name, member)
|
678
|
+
"#{leaderboard_name}:member_data:#{member}"
|
679
|
+
end
|
680
|
+
|
604
681
|
# Validate and return the page size. Returns the +DEFAULT_PAGE_SIZE+ if the page size is less than 1.
|
605
682
|
#
|
606
683
|
# @param page_size [int] Page size.
|
data/lib/leaderboard/version.rb
CHANGED
data/spec/leaderboard_spec.rb
CHANGED
@@ -139,6 +139,42 @@ describe 'Leaderboard' do
|
|
139
139
|
leaders[24].should == member_1
|
140
140
|
end
|
141
141
|
|
142
|
+
it 'should allow you to retrieve leaders with extra data' do
|
143
|
+
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE)
|
144
|
+
|
145
|
+
@leaderboard.total_members.should be(Leaderboard::DEFAULT_PAGE_SIZE)
|
146
|
+
leaders = @leaderboard.leaders(1, {:with_scores => false, :with_rank => false, :with_member_data => true})
|
147
|
+
|
148
|
+
member_25 = {:member => 'member_25', :member_data => { "member_name" => "Leaderboard member 25" }}
|
149
|
+
leaders[0].should == member_25
|
150
|
+
|
151
|
+
member_1 = {:member => 'member_1', :member_data => { "member_name" => "Leaderboard member 1" }}
|
152
|
+
leaders[24].should == member_1
|
153
|
+
end
|
154
|
+
|
155
|
+
it 'should allow you to retrieve optional member data' do
|
156
|
+
@leaderboard.rank_member('member_id', 1, {'username' => 'member_name', 'other_data_key' => 'other_data_value'})
|
157
|
+
|
158
|
+
@leaderboard.member_data_for('unknown_member').should == {}
|
159
|
+
@leaderboard.member_data_for('member_id').should == {'username' => 'member_name', 'other_data_key' => 'other_data_value'}
|
160
|
+
end
|
161
|
+
|
162
|
+
it 'should allow you to update optional member data' do
|
163
|
+
@leaderboard.rank_member('member_id', 1, {'username' => 'member_name'})
|
164
|
+
|
165
|
+
@leaderboard.member_data_for('member_id').should == {'username' => 'member_name'}
|
166
|
+
@leaderboard.update_member_data('member_id', {'other_data_key' => 'other_data_value'})
|
167
|
+
@leaderboard.member_data_for('member_id').should == {'username' => 'member_name', 'other_data_key' => 'other_data_value'}
|
168
|
+
end
|
169
|
+
|
170
|
+
it 'should allow you to remove optional member data' do
|
171
|
+
@leaderboard.rank_member('member_id', 1, {'username' => 'member_name'})
|
172
|
+
|
173
|
+
@leaderboard.member_data_for('member_id').should == {'username' => 'member_name'}
|
174
|
+
@leaderboard.remove_member_data('member_id')
|
175
|
+
@leaderboard.member_data_for('member_id').should == {}
|
176
|
+
end
|
177
|
+
|
142
178
|
it 'should allow you to call leaders with various options that respect the defaults for the options not passed in' do
|
143
179
|
rank_members_in_leaderboard(Leaderboard::DEFAULT_PAGE_SIZE + 1)
|
144
180
|
|
data/spec/spec_helper.rb
CHANGED
@@ -9,7 +9,7 @@ RSpec.configure do |config|
|
|
9
9
|
# @param members_to_add [int] Number of members to add to the leaderboard.
|
10
10
|
def rank_members_in_leaderboard(members_to_add = 5)
|
11
11
|
1.upto(members_to_add) do |index|
|
12
|
-
@leaderboard.rank_member("member_#{index}", index)
|
12
|
+
@leaderboard.rank_member("member_#{index}", index, { :member_name => "Leaderboard member #{index}" })
|
13
13
|
end
|
14
14
|
end
|
15
15
|
end
|
data/spec/version_spec.rb
CHANGED
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: leaderboard
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.0
|
4
|
+
version: 2.1.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,11 +9,11 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2012-
|
12
|
+
date: 2012-06-11 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: redis
|
16
|
-
requirement:
|
16
|
+
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
19
|
- - ! '>='
|
@@ -21,10 +21,15 @@ dependencies:
|
|
21
21
|
version: '0'
|
22
22
|
type: :runtime
|
23
23
|
prerelease: false
|
24
|
-
version_requirements:
|
24
|
+
version_requirements: !ruby/object:Gem::Requirement
|
25
|
+
none: false
|
26
|
+
requirements:
|
27
|
+
- - ! '>='
|
28
|
+
- !ruby/object:Gem::Version
|
29
|
+
version: '0'
|
25
30
|
- !ruby/object:Gem::Dependency
|
26
31
|
name: rake
|
27
|
-
requirement:
|
32
|
+
requirement: !ruby/object:Gem::Requirement
|
28
33
|
none: false
|
29
34
|
requirements:
|
30
35
|
- - ! '>='
|
@@ -32,10 +37,15 @@ dependencies:
|
|
32
37
|
version: '0'
|
33
38
|
type: :development
|
34
39
|
prerelease: false
|
35
|
-
version_requirements:
|
40
|
+
version_requirements: !ruby/object:Gem::Requirement
|
41
|
+
none: false
|
42
|
+
requirements:
|
43
|
+
- - ! '>='
|
44
|
+
- !ruby/object:Gem::Version
|
45
|
+
version: '0'
|
36
46
|
- !ruby/object:Gem::Dependency
|
37
47
|
name: rspec
|
38
|
-
requirement:
|
48
|
+
requirement: !ruby/object:Gem::Requirement
|
39
49
|
none: false
|
40
50
|
requirements:
|
41
51
|
- - ! '>='
|
@@ -43,7 +53,12 @@ dependencies:
|
|
43
53
|
version: '0'
|
44
54
|
type: :development
|
45
55
|
prerelease: false
|
46
|
-
version_requirements:
|
56
|
+
version_requirements: !ruby/object:Gem::Requirement
|
57
|
+
none: false
|
58
|
+
requirements:
|
59
|
+
- - ! '>='
|
60
|
+
- !ruby/object:Gem::Version
|
61
|
+
version: '0'
|
47
62
|
description: Leaderboards backed by Redis in Ruby
|
48
63
|
email:
|
49
64
|
- dczarnecki@agoragames.com
|
@@ -82,7 +97,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
82
97
|
version: '0'
|
83
98
|
segments:
|
84
99
|
- 0
|
85
|
-
hash:
|
100
|
+
hash: 248515504144092266
|
86
101
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
87
102
|
none: false
|
88
103
|
requirements:
|
@@ -91,10 +106,10 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
91
106
|
version: '0'
|
92
107
|
segments:
|
93
108
|
- 0
|
94
|
-
hash:
|
109
|
+
hash: 248515504144092266
|
95
110
|
requirements: []
|
96
111
|
rubyforge_project: leaderboard
|
97
|
-
rubygems_version: 1.8.
|
112
|
+
rubygems_version: 1.8.23
|
98
113
|
signing_key:
|
99
114
|
specification_version: 3
|
100
115
|
summary: Leaderboards backed by Redis in Ruby
|