redis-objects 0.1.0 → 0.1.1
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/README.rdoc +54 -19
- data/lib/redis/counter.rb +2 -3
- data/lib/redis/list.rb +40 -30
- data/lib/redis/lock.rb +2 -2
- data/lib/redis/objects/counters.rb +1 -1
- data/lib/redis/objects/lists.rb +1 -1
- data/lib/redis/objects/locks.rb +1 -1
- data/lib/redis/objects/sets.rb +25 -0
- data/lib/redis/objects/values.rb +1 -1
- data/lib/redis/set.rb +68 -0
- data/lib/redis/value.rb +2 -2
- data/spec/redis_objects_model_spec.rb +100 -0
- metadata +4 -4
data/README.rdoc
CHANGED
@@ -4,13 +4,12 @@ This is *not* an ORM. People that are wrapping ORM's around Redis are missing
|
|
4
4
|
the point.
|
5
5
|
|
6
6
|
The killer feature of Redis that it allows you to perform atomic operations
|
7
|
-
on _individual_ data structures, like counters, lists, and sets
|
8
|
-
*with* your existing ActiveRecord/DataMapper/etc models, or in classes that have
|
7
|
+
on _individual_ data structures, like counters, lists, and sets. You can then use
|
8
|
+
these *with* your existing ActiveRecord/DataMapper/etc models, or in classes that have
|
9
9
|
nothing to do with an ORM or even a database. That's where this gem comes in.
|
10
10
|
|
11
|
-
|
12
|
-
|
13
|
-
games; for a fun rant on the topic, see
|
11
|
+
This gem originally arose out of a need for high-concurrency atomic operations;
|
12
|
+
for a fun rant on the topic, see
|
14
13
|
{ATOMICITY}[http://github.com/nateware/redis-objects/blob/master/ATOMICITY.rdoc],
|
15
14
|
or scroll down to "Atomicity" in this README.
|
16
15
|
|
@@ -23,6 +22,8 @@ by using +new+ with the type of data structure you want to create.
|
|
23
22
|
gem tumble
|
24
23
|
gem install redis-objects
|
25
24
|
|
25
|
+
== Example 1: Class Usage
|
26
|
+
|
26
27
|
=== Initialization
|
27
28
|
|
28
29
|
# If on Rails, config/initializers/redis.rb is a good place for this
|
@@ -30,42 +31,76 @@ by using +new+ with the type of data structure you want to create.
|
|
30
31
|
require 'redis/objects'
|
31
32
|
Redis::Objects.redis = Redis.new(:host => 127.0.0.1, :port => 6379)
|
32
33
|
|
33
|
-
|
34
|
+
=== Model Class
|
34
35
|
|
35
|
-
|
36
|
+
Include in any type of class:
|
36
37
|
|
37
38
|
class Team < ActiveRecord::Base
|
38
39
|
include Redis::Objects
|
39
40
|
|
40
|
-
counter :
|
41
|
-
counter :
|
42
|
-
counter :
|
41
|
+
counter :hits
|
42
|
+
counter :runs
|
43
|
+
counter :outs
|
44
|
+
counter :inning, :start => 1
|
43
45
|
list :on_base
|
44
46
|
set :outfielders
|
45
|
-
value :
|
47
|
+
value :at_bat
|
46
48
|
end
|
47
49
|
|
48
|
-
Familiar Ruby operations Just Work:
|
50
|
+
Familiar Ruby array operations Just Work (TM):
|
49
51
|
|
50
52
|
@team = Team.find(1)
|
51
53
|
@team.on_base << 'player1'
|
52
54
|
@team.on_base << 'player2'
|
53
|
-
|
55
|
+
@team.on_base << 'player3'
|
56
|
+
puts @team.on_base # ['player1', 'player2']
|
54
57
|
@team.on_base.pop
|
58
|
+
@team.on_base.shift
|
59
|
+
@team.on_base.length # 1
|
60
|
+
@team.on_base.delete('player3')
|
61
|
+
|
62
|
+
Sets work like the Ruby {Set}[http://ruby-doc.org/core/classes/Set.html] class:
|
63
|
+
|
64
|
+
@team.outfielders['1b'] = 'outfielder1'
|
65
|
+
@team.outfielders['lf'] = 'outfielder3'
|
66
|
+
@team.outfielders['lf'] = 'outfielder2'
|
67
|
+
@team.outfielders.keys
|
68
|
+
@team.outfielders.each do |position,player|
|
69
|
+
puts "#{player} is playing #{position}"
|
70
|
+
end
|
71
|
+
position = @team.outfielders.detect{|pos,of| of == 'outfielder3'}
|
72
|
+
|
73
|
+
Note counters cannot be assigned to, only incremented/decremented:
|
74
|
+
|
75
|
+
@team.hits.increment # or incr
|
76
|
+
@team.hits.decrement # or decr
|
77
|
+
@team.runs = 4 # exception
|
78
|
+
@team.runs += 1 # exception
|
55
79
|
|
56
|
-
|
80
|
+
It would be cool to get that last one working, but Ruby's implementation of +=
|
81
|
+
is problematic.
|
57
82
|
|
58
|
-
|
59
|
-
@team.drafted_players.decrement # or decr
|
60
|
-
@team.drafted_players = 4 # exception
|
61
|
-
@team.drafted_players += 1 # exception
|
83
|
+
== Example 2: Instance Usage
|
62
84
|
|
63
|
-
|
85
|
+
Each data type can be used independently.
|
86
|
+
|
87
|
+
=== Initialization
|
88
|
+
|
89
|
+
Can follow the +$redis+ global variable pattern:
|
90
|
+
|
91
|
+
$redis = Redis.new(:host => 'localhost', :port => 6379)
|
92
|
+
@value = Redis::Value.new('myvalue')
|
93
|
+
|
94
|
+
Or can pass the handle into the new method:
|
95
|
+
|
96
|
+
redis = Redis.new(:host => 'localhost', :port => 6379)
|
97
|
+
@value = Redis::Value.new('myvalue', redis)
|
64
98
|
|
65
99
|
=== Counters
|
66
100
|
|
67
101
|
@counter = Redis::Counter.new('counter_name')
|
68
102
|
@counter.increment
|
103
|
+
@counter.decrement
|
69
104
|
puts @counter
|
70
105
|
puts @counter.get # force re-fetch
|
71
106
|
|
data/lib/redis/counter.rb
CHANGED
@@ -8,12 +8,11 @@ class Redis
|
|
8
8
|
#
|
9
9
|
class Counter
|
10
10
|
attr_reader :key, :options, :redis
|
11
|
-
def initialize(key, options={})
|
11
|
+
def initialize(key, redis=$redis, options={})
|
12
12
|
@key = key
|
13
|
+
@redis = redis
|
13
14
|
@options = options
|
14
|
-
@redis = options[:redis] || $redis || Redis::Objects.redis
|
15
15
|
@options[:start] ||= 0
|
16
|
-
@options[:type] ||= @options[:start] == 0 ? :increment : :decrement
|
17
16
|
@redis.setnx(key, @options[:start]) unless @options[:start] == 0 || @options[:init] === false
|
18
17
|
end
|
19
18
|
|
data/lib/redis/list.rb
CHANGED
@@ -4,71 +4,77 @@ class Redis
|
|
4
4
|
# behave as much like Ruby arrays as possible.
|
5
5
|
#
|
6
6
|
class List
|
7
|
+
require 'enumerator'
|
8
|
+
include Enumerable
|
9
|
+
|
7
10
|
attr_reader :key, :options, :redis
|
8
|
-
def initialize(key, options={})
|
11
|
+
def initialize(key, redis=$redis, options={})
|
9
12
|
@key = key
|
13
|
+
@redis = redis
|
10
14
|
@options = options
|
11
|
-
@redis = options[:redis] || $redis || Redis::Objects.redis
|
12
|
-
@options[:start] ||= 0
|
13
|
-
@options[:type] ||= @options[:start] == 0 ? :increment : :decrement
|
14
|
-
@redis.setnx(key, @options[:start]) unless @options[:start] == 0 || @options[:init] === false
|
15
15
|
end
|
16
|
-
|
16
|
+
|
17
|
+
# Works like push. Can chain together: list << 'a' << 'b'
|
17
18
|
def <<(value)
|
18
19
|
push(value)
|
20
|
+
self # for << 'a' << 'b'
|
19
21
|
end
|
20
|
-
|
22
|
+
|
23
|
+
# Add a member to the end of the list. Redis: RPUSH
|
21
24
|
def push(value)
|
22
25
|
redis.rpush(key, value)
|
23
|
-
@values << value
|
24
26
|
end
|
25
27
|
|
28
|
+
# Remove a member from the end of the list. Redis: RPOP
|
26
29
|
def pop
|
27
30
|
redis.rpop(key)
|
28
|
-
@values.pop
|
29
31
|
end
|
30
32
|
|
33
|
+
# Add a member to the start of the list. Redis: LPUSH
|
31
34
|
def unshift(value)
|
32
35
|
redis.lpush(key, value)
|
33
|
-
@values.unshift value
|
34
36
|
end
|
35
37
|
|
38
|
+
# Remove a member from the start of the list. Redis: LPOP
|
36
39
|
def shift
|
37
40
|
redis.lpop(key)
|
38
41
|
end
|
39
42
|
|
43
|
+
# Return all values in the list. Redis: LRANGE(0,-1)
|
40
44
|
def values
|
41
|
-
|
45
|
+
range(0, -1)
|
42
46
|
end
|
47
|
+
alias_method :get, :values
|
43
48
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
def get
|
50
|
-
@values = range(0, -1)
|
51
|
-
end
|
52
|
-
|
53
|
-
def [](index)
|
54
|
-
case index
|
55
|
-
when Range
|
49
|
+
# Same functionality as Ruby arrays. If a single number is given, return
|
50
|
+
# just the element at that index using Redis: LINDEX. Otherwise, return
|
51
|
+
# a range of values using Redis: LRANGE.
|
52
|
+
def [](index, length=nil)
|
53
|
+
if index.is_a? Range
|
56
54
|
range(index.first, index.last)
|
55
|
+
elsif length
|
56
|
+
range(index, length)
|
57
57
|
else
|
58
|
-
|
58
|
+
at(index)
|
59
59
|
end
|
60
60
|
end
|
61
61
|
|
62
62
|
def delete(name, count=0)
|
63
|
-
redis.lrem(
|
63
|
+
redis.lrem(key, count, name) # weird api
|
64
|
+
get
|
65
|
+
end
|
66
|
+
|
67
|
+
def each(&block)
|
68
|
+
values.each(&block)
|
64
69
|
end
|
65
70
|
|
66
71
|
def range(start_index, end_index)
|
67
72
|
redis.lrange(key, start_index, end_index)
|
68
73
|
end
|
69
|
-
|
74
|
+
|
75
|
+
# Return the value at the given index.
|
70
76
|
def at(index)
|
71
|
-
redis.
|
77
|
+
redis.lindex(key, index)
|
72
78
|
end
|
73
79
|
|
74
80
|
def last
|
@@ -80,16 +86,20 @@ class Redis
|
|
80
86
|
end
|
81
87
|
|
82
88
|
def length
|
83
|
-
redis.
|
89
|
+
redis.llen(key)
|
84
90
|
end
|
85
91
|
alias_method :size, :length
|
86
92
|
|
87
93
|
def empty?
|
88
|
-
|
94
|
+
length == 0
|
89
95
|
end
|
90
|
-
|
96
|
+
|
91
97
|
def ==(x)
|
92
98
|
values == x
|
93
99
|
end
|
100
|
+
|
101
|
+
def to_s
|
102
|
+
values.join(', ')
|
103
|
+
end
|
94
104
|
end
|
95
105
|
end
|
data/lib/redis/lock.rb
CHANGED
@@ -10,11 +10,11 @@ class Redis
|
|
10
10
|
class LockTimeout < StandardError; end #:nodoc:
|
11
11
|
|
12
12
|
attr_reader :key, :options, :redis
|
13
|
-
def initialize(key, options={})
|
13
|
+
def initialize(key, redis=$redis, options={})
|
14
14
|
@key = key
|
15
|
+
@redis = redis
|
15
16
|
@options = options
|
16
17
|
@options[:timeout] ||= 5
|
17
|
-
@redis = options[:redis] || $redis || Redis::Objects.redis
|
18
18
|
@redis.setnx(key, @options[:start]) unless @options[:start] == 0 || @options[:init] === false
|
19
19
|
end
|
20
20
|
|
@@ -24,7 +24,7 @@ class Redis
|
|
24
24
|
@counters[name] = options
|
25
25
|
class_eval <<-EndMethods
|
26
26
|
def #{name}
|
27
|
-
@#{name} ||= Redis::Counter.new(field_key(:#{name}), self.class.counters[:#{name}]
|
27
|
+
@#{name} ||= Redis::Counter.new(field_key(:#{name}), redis, self.class.counters[:#{name}])
|
28
28
|
end
|
29
29
|
EndMethods
|
30
30
|
end
|
data/lib/redis/objects/lists.rb
CHANGED
@@ -20,7 +20,7 @@ class Redis
|
|
20
20
|
@lists[name] = options
|
21
21
|
class_eval <<-EndMethods
|
22
22
|
def #{name}
|
23
|
-
@#{name} ||= Redis::List.new(field_key(:#{name}), self.class.lists[:#{name}]
|
23
|
+
@#{name} ||= Redis::List.new(field_key(:#{name}), redis, self.class.lists[:#{name}])
|
24
24
|
end
|
25
25
|
EndMethods
|
26
26
|
end
|
data/lib/redis/objects/locks.rb
CHANGED
@@ -22,7 +22,7 @@ class Redis
|
|
22
22
|
@locks[name] = options
|
23
23
|
class_eval <<-EndMethods
|
24
24
|
def #{name}_lock(&block)
|
25
|
-
@#{name}_lock ||= Redis::Lock.new(field_key(:#{name}_lock), self.class.locks[:#{name}]
|
25
|
+
@#{name}_lock ||= Redis::Lock.new(field_key(:#{name}_lock), redis, self.class.locks[:#{name}])
|
26
26
|
end
|
27
27
|
EndMethods
|
28
28
|
end
|
data/lib/redis/objects/sets.rb
CHANGED
@@ -4,6 +4,31 @@ require 'redis/set'
|
|
4
4
|
class Redis
|
5
5
|
module Objects
|
6
6
|
module Sets
|
7
|
+
def self.included(klass)
|
8
|
+
klass.instance_variable_set('@sets', {})
|
9
|
+
klass.send :include, InstanceMethods
|
10
|
+
klass.extend ClassMethods
|
11
|
+
end
|
12
|
+
|
13
|
+
# Class methods that appear in your class when you include Redis::Objects.
|
14
|
+
module ClassMethods
|
15
|
+
attr_reader :sets
|
16
|
+
|
17
|
+
# Define a new list. It will function like a regular instance
|
18
|
+
# method, so it can be used alongside ActiveRecord, DataMapper, etc.
|
19
|
+
def set(name, options={})
|
20
|
+
@sets[name] = options
|
21
|
+
class_eval <<-EndMethods
|
22
|
+
def #{name}
|
23
|
+
@#{name} ||= Redis::Set.new(field_key(:#{name}), redis, self.class.sets[:#{name}])
|
24
|
+
end
|
25
|
+
EndMethods
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
# Instance methods that appear in your class when you include Redis::Objects.
|
30
|
+
module InstanceMethods
|
31
|
+
end
|
7
32
|
end
|
8
33
|
end
|
9
34
|
end
|
data/lib/redis/objects/values.rb
CHANGED
@@ -20,7 +20,7 @@ class Redis
|
|
20
20
|
@values[name] = options
|
21
21
|
class_eval <<-EndMethods
|
22
22
|
def #{name}
|
23
|
-
@#{name} ||= Redis::Value.new(field_key(:#{name}), self.class.values[:#{name}]
|
23
|
+
@#{name} ||= Redis::Value.new(field_key(:#{name}), redis, self.class.values[:#{name}])
|
24
24
|
end
|
25
25
|
def #{name}=(value)
|
26
26
|
#{name}.value = value
|
data/lib/redis/set.rb
CHANGED
@@ -3,5 +3,73 @@ class Redis
|
|
3
3
|
# Class representing a set.
|
4
4
|
#
|
5
5
|
class Set
|
6
|
+
require 'enumerator'
|
7
|
+
include Enumerable
|
8
|
+
|
9
|
+
attr_reader :key, :options, :redis
|
10
|
+
def initialize(key, redis=$redis, options={})
|
11
|
+
@key = key
|
12
|
+
@redis = redis
|
13
|
+
@options = options
|
14
|
+
end
|
15
|
+
|
16
|
+
# Works like add. Can chain together: list << 'a' << 'b'
|
17
|
+
def <<(value)
|
18
|
+
add(value)
|
19
|
+
self # for << 'a' << 'b'
|
20
|
+
end
|
21
|
+
|
22
|
+
# Add the specified value to the set only if it does not exist already.
|
23
|
+
# Redis: SADD
|
24
|
+
def add(value)
|
25
|
+
redis.sadd(key, value)
|
26
|
+
end
|
27
|
+
|
28
|
+
# Return all members in the set. Redis: SMEMBERS
|
29
|
+
def members
|
30
|
+
redis.smembers(key)
|
31
|
+
end
|
32
|
+
alias_method :get, :members
|
33
|
+
|
34
|
+
# Returns true if the specified value is in the set. Redis: SISMEMBER
|
35
|
+
def member?(value)
|
36
|
+
redis.sismember(key, value)
|
37
|
+
end
|
38
|
+
|
39
|
+
# Delete the value from the set. Redis: SREM
|
40
|
+
def delete(name)
|
41
|
+
redis.srem(key, name)
|
42
|
+
get
|
43
|
+
end
|
44
|
+
|
45
|
+
# Wipe the set entirely. Redis: DEL
|
46
|
+
def clear
|
47
|
+
redis.del(key)
|
48
|
+
end
|
49
|
+
|
50
|
+
# Iterate through each member of the set. Redis::Objects mixes in Enumerable,
|
51
|
+
# so you can also use familiar methods like +collect+, +detect+, and so forth.
|
52
|
+
def each(&block)
|
53
|
+
members.each(&block)
|
54
|
+
end
|
55
|
+
|
56
|
+
# The number of members in the set. Aliased as size. Redis: SCARD
|
57
|
+
def length
|
58
|
+
redis.scard(key)
|
59
|
+
end
|
60
|
+
alias_method :size, :length
|
61
|
+
|
62
|
+
# Returns true if the set has no members. Redis: SCARD == 0
|
63
|
+
def empty?
|
64
|
+
length == 0
|
65
|
+
end
|
66
|
+
|
67
|
+
def ==(x)
|
68
|
+
members == x
|
69
|
+
end
|
70
|
+
|
71
|
+
def to_s
|
72
|
+
members.join(', ')
|
73
|
+
end
|
6
74
|
end
|
7
75
|
end
|
data/lib/redis/value.rb
CHANGED
@@ -4,10 +4,10 @@ class Redis
|
|
4
4
|
#
|
5
5
|
class Value
|
6
6
|
attr_reader :key, :options, :redis
|
7
|
-
def initialize(key, options={})
|
7
|
+
def initialize(key, redis=$redis, options={})
|
8
8
|
@key = key
|
9
|
+
@redis = redis
|
9
10
|
@options = options
|
10
|
-
@redis = options[:redis] || $redis || Redis::Objects.redis
|
11
11
|
@redis.setnx(key, @options[:default]) if @options[:default]
|
12
12
|
end
|
13
13
|
|
@@ -10,6 +10,7 @@ class Roster
|
|
10
10
|
lock :resort, :timeout => 2
|
11
11
|
value :starting_pitcher
|
12
12
|
list :player_stats
|
13
|
+
set :outfielders
|
13
14
|
|
14
15
|
def initialize(id=1) @id = id end
|
15
16
|
def id; @id; end
|
@@ -29,6 +30,7 @@ describe Redis::Objects do
|
|
29
30
|
@roster.resort_lock.clear
|
30
31
|
@roster.starting_pitcher.delete
|
31
32
|
@roster.player_stats.clear
|
33
|
+
@roster.outfielders.clear
|
32
34
|
end
|
33
35
|
|
34
36
|
it "should provide a connection method" do
|
@@ -254,6 +256,104 @@ describe Redis::Objects do
|
|
254
256
|
@roster.player_stats.should be_empty
|
255
257
|
@roster.player_stats << 'a'
|
256
258
|
@roster.player_stats.should == ['a']
|
259
|
+
@roster.player_stats.get.should == ['a']
|
260
|
+
@roster.player_stats.unshift 'b'
|
261
|
+
@roster.player_stats.to_s.should == 'b, a'
|
262
|
+
@roster.player_stats.should == ['b','a']
|
263
|
+
@roster.player_stats.get.should == ['b','a']
|
264
|
+
@roster.player_stats.push 'c'
|
265
|
+
@roster.player_stats.should == ['b','a','c']
|
266
|
+
@roster.player_stats.get.should == ['b','a','c']
|
267
|
+
@roster.player_stats << 'd'
|
268
|
+
@roster.player_stats.should == ['b','a','c','d']
|
269
|
+
@roster.player_stats[1].should == 'a'
|
270
|
+
@roster.player_stats[0].should == 'b'
|
271
|
+
@roster.player_stats[2].should == 'c'
|
272
|
+
@roster.player_stats[3].should == 'd'
|
273
|
+
@roster.player_stats.pop
|
274
|
+
@roster.player_stats[0].should == @roster.player_stats.at(0)
|
275
|
+
@roster.player_stats[1].should == @roster.player_stats.at(1)
|
276
|
+
@roster.player_stats[2].should == @roster.player_stats.at(2)
|
277
|
+
@roster.player_stats.should == ['b','a','c']
|
278
|
+
@roster.player_stats.get.should == ['b','a','c']
|
279
|
+
@roster.player_stats.shift
|
280
|
+
@roster.player_stats.should == ['a','c']
|
281
|
+
@roster.player_stats.get.should == ['a','c']
|
282
|
+
@roster.player_stats << 'e' << 'f' << 'e'
|
283
|
+
@roster.player_stats.should == ['a','c','e','f','e']
|
284
|
+
@roster.player_stats.get.should == ['a','c','e','f','e']
|
285
|
+
@roster.player_stats.delete('e')
|
286
|
+
@roster.player_stats.should == ['a','c','f']
|
287
|
+
@roster.player_stats.get.should == ['a','c','f']
|
288
|
+
@roster.player_stats << 'j'
|
289
|
+
@roster.player_stats.should == ['a','c','f','j']
|
290
|
+
@roster.player_stats[0..2].should == ['a','c','f']
|
291
|
+
@roster.player_stats[1, 3].should == ['c','f','j']
|
292
|
+
@roster.player_stats.length.should == 4
|
293
|
+
@roster.player_stats.size.should == 4
|
294
|
+
@roster.player_stats.should == ['a','c','f','j']
|
295
|
+
@roster.player_stats.get.should == ['a','c','f','j']
|
296
|
+
|
297
|
+
i = -1
|
298
|
+
@roster.player_stats.each do |st|
|
299
|
+
st.should == @roster.player_stats[i += 1]
|
300
|
+
end
|
301
|
+
@roster.player_stats.should == ['a','c','f','j']
|
302
|
+
@roster.player_stats.get.should == ['a','c','f','j']
|
303
|
+
|
304
|
+
@roster.player_stats.each_with_index do |st,i|
|
305
|
+
st.should == @roster.player_stats[i]
|
306
|
+
end
|
307
|
+
@roster.player_stats.should == ['a','c','f','j']
|
308
|
+
@roster.player_stats.get.should == ['a','c','f','j']
|
309
|
+
|
310
|
+
coll = @roster.player_stats.collect{|st| st}
|
311
|
+
coll.should == ['a','c','f','j']
|
312
|
+
@roster.player_stats.should == ['a','c','f','j']
|
313
|
+
@roster.player_stats.get.should == ['a','c','f','j']
|
314
|
+
|
315
|
+
@roster.player_stats << 'a'
|
316
|
+
coll = @roster.player_stats.select{|st| st == 'a'}
|
317
|
+
coll.should == ['a','a']
|
318
|
+
@roster.player_stats.should == ['a','c','f','j','a']
|
319
|
+
@roster.player_stats.get.should == ['a','c','f','j','a']
|
320
|
+
end
|
321
|
+
|
322
|
+
it "should handle sets of simple values" do
|
323
|
+
@roster.outfielders.should be_empty
|
324
|
+
@roster.outfielders << 'a' << 'a' << 'a'
|
325
|
+
@roster.outfielders.should == ['a']
|
326
|
+
@roster.outfielders.get.should == ['a']
|
327
|
+
@roster.outfielders << 'b' << 'b'
|
328
|
+
@roster.outfielders.to_s.should == 'a, b'
|
329
|
+
@roster.outfielders.should == ['a','b']
|
330
|
+
@roster.outfielders.members.should == ['a','b']
|
331
|
+
@roster.outfielders.get.should == ['a','b']
|
332
|
+
@roster.outfielders << 'c'
|
333
|
+
@roster.outfielders.sort.should == ['a','b','c']
|
334
|
+
@roster.outfielders.get.sort.should == ['a','b','c']
|
335
|
+
@roster.outfielders.delete('c')
|
336
|
+
@roster.outfielders.should == ['a','b']
|
337
|
+
@roster.outfielders.get.sort.should == ['a','b']
|
338
|
+
@roster.outfielders.length.should == 2
|
339
|
+
@roster.outfielders.size.should == 2
|
340
|
+
|
341
|
+
i = 0
|
342
|
+
@roster.outfielders.each do |st|
|
343
|
+
i += 1
|
344
|
+
end
|
345
|
+
i.should == @roster.outfielders.length
|
346
|
+
|
347
|
+
coll = @roster.outfielders.collect{|st| st}
|
348
|
+
coll.should == ['a','b']
|
349
|
+
@roster.outfielders.should == ['a','b']
|
350
|
+
@roster.outfielders.get.should == ['a','b']
|
351
|
+
|
352
|
+
@roster.outfielders << 'c'
|
353
|
+
@roster.outfielders.member? 'c'
|
354
|
+
coll = @roster.outfielders.select{|st| st == 'c'}
|
355
|
+
coll.should == ['c']
|
356
|
+
@roster.outfielders.sort.should == ['a','b','c']
|
257
357
|
end
|
258
358
|
|
259
359
|
it "should provide a lock method that accepts a block" do
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: redis-objects
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.1.
|
4
|
+
version: 0.1.1
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Nate Wiger
|
@@ -9,11 +9,11 @@ autorequire:
|
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
11
|
|
12
|
-
date: 2009-11-
|
12
|
+
date: 2009-11-26 00:00:00 -08:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|
16
|
-
description: Redis
|
16
|
+
description: Map Redis types directly to Ruby objects. Works with any class or ORM.
|
17
17
|
email: nate@wiger.org
|
18
18
|
executables: []
|
19
19
|
|
@@ -68,6 +68,6 @@ rubyforge_project: redis-objects
|
|
68
68
|
rubygems_version: 1.3.5
|
69
69
|
signing_key:
|
70
70
|
specification_version: 3
|
71
|
-
summary:
|
71
|
+
summary: Maps Redis types to Ruby objects
|
72
72
|
test_files: []
|
73
73
|
|