redis-objects 0.1.0 → 0.1.1
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|