rev_memcache 0.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.
@@ -0,0 +1,5 @@
1
+ README.rdoc
2
+ lib/**/*.rb
3
+ bin/*
4
+ features/**/*.feature
5
+ LICENSE
@@ -0,0 +1,21 @@
1
+ ## MAC OS
2
+ .DS_Store
3
+
4
+ ## TEXTMATE
5
+ *.tmproj
6
+ tmtags
7
+
8
+ ## EMACS
9
+ *~
10
+ \#*
11
+ .\#*
12
+
13
+ ## VIM
14
+ *.swp
15
+
16
+ ## PROJECT::GENERAL
17
+ coverage
18
+ rdoc
19
+ pkg
20
+
21
+ ## PROJECT::SPECIFIC
data/LICENSE ADDED
@@ -0,0 +1,20 @@
1
+ Copyright (c) 2009 Andrew Rudenko
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.
@@ -0,0 +1,17 @@
1
+ = rev_memcache
2
+
3
+ Description goes here.
4
+
5
+ == Note on Patches/Pull Requests
6
+
7
+ * Fork the project.
8
+ * Make your feature addition or bug fix.
9
+ * Add tests for it. This is important so I don't break it in a
10
+ future version unintentionally.
11
+ * Commit, do not mess with rakefile, version, or history.
12
+ (if you want to have your own version, that is fine but bump version in a commit by itself I can ignore when I pull)
13
+ * Send me a pull request. Bonus points for topic branches.
14
+
15
+ == Copyright
16
+
17
+ Copyright (c) 2010 Andrew Rudenko. See LICENSE for details.
@@ -0,0 +1,52 @@
1
+ require 'rubygems'
2
+ require 'rake'
3
+
4
+ begin
5
+ require 'jeweler'
6
+ Jeweler::Tasks.new do |gem|
7
+ gem.name = "rev_memcache"
8
+ gem.summary = %Q{Rev memcache client}
9
+ gem.description = %Q{Rev memcache client}
10
+ gem.email = "ceo@prepor.ru"
11
+ gem.homepage = "http://github.com/prepor/rev_memcache"
12
+ gem.authors = ["Andrew Rudenko"]
13
+ gem.add_dependency "rev", ">= 0"
14
+ end
15
+ Jeweler::GemcutterTasks.new
16
+ rescue LoadError
17
+ puts "Jeweler (or a dependency) not available. Install it with: gem install jeweler"
18
+ end
19
+
20
+ require 'rake/testtask'
21
+ Rake::TestTask.new(:test) do |test|
22
+ test.libs << 'lib' << 'test'
23
+ test.pattern = 'test/**/test_*.rb'
24
+ test.verbose = true
25
+ end
26
+
27
+ begin
28
+ require 'rcov/rcovtask'
29
+ Rcov::RcovTask.new do |test|
30
+ test.libs << 'test'
31
+ test.pattern = 'test/**/test_*.rb'
32
+ test.verbose = true
33
+ end
34
+ rescue LoadError
35
+ task :rcov do
36
+ abort "RCov is not available. In order to run rcov, you must: sudo gem install spicycode-rcov"
37
+ end
38
+ end
39
+
40
+ task :test => :check_dependencies
41
+
42
+ task :default => :test
43
+
44
+ require 'rake/rdoctask'
45
+ Rake::RDocTask.new do |rdoc|
46
+ version = File.exist?('VERSION') ? File.read('VERSION') : ""
47
+
48
+ rdoc.rdoc_dir = 'rdoc'
49
+ rdoc.title = "rev_memcache #{version}"
50
+ rdoc.rdoc_files.include('README*')
51
+ rdoc.rdoc_files.include('lib/**/*.rb')
52
+ end
data/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.1.0
@@ -0,0 +1,25 @@
1
+ require 'rubygems'
2
+ require 'rev'
3
+ require File.dirname(__FILE__) + '/../lib/rev_memcache'
4
+
5
+ event_loop = Rev::Loop.default
6
+ cache = Rev::Memcache.connect('localhost', 11211).attach(event_loop)
7
+
8
+ cache.set :a, 'hello'
9
+ cache.set :b, 'hi'
10
+ cache.set :c, 'how are you?'
11
+ cache.set :d, ''
12
+
13
+ cache.get(:a){ |v| p v }
14
+ cache.get_hash(:a, :b, :c, :d){ |v| p v }
15
+ cache.get(:a,:b,:c,:d){ |a,b,c,d| p [a,b,c,d] }
16
+
17
+ cache.get(:a,:z,:b,:y,:d){ |a,z,b,y,d| p [a,z,b,y,d] }
18
+
19
+ cache.get(:missing){ |m| p [:missing=, m] }
20
+ cache.set(:missing, 'abc'){ p :stored }
21
+ cache.get(:missing){ |m| p [:missing=, m] }
22
+ cache.del(:missing){ p :deleted }
23
+ cache.get(:missing){ |m| p [:missing=, m] }
24
+
25
+ event_loop.run
@@ -0,0 +1,205 @@
1
+ module Rev
2
+ # Implements the Memcache protocol (http://code.sixapart.com/svn/memcached/trunk/server/doc/protocol.txt).
3
+ # Requires memcached >= 1.2.4 w/ noreply support
4
+ #
5
+ # == Usage example
6
+ #
7
+ # EM.run{
8
+ # cache = EM::P::Memcache.connect 'localhost', 11211
9
+ #
10
+ # cache.set :a, 'hello'
11
+ # cache.set :b, 'hi'
12
+ # cache.set :c, 'how are you?'
13
+ # cache.set :d, ''
14
+ #
15
+ # cache.get(:a){ |v| p v }
16
+ # cache.get_hash(:a, :b, :c, :d){ |v| p v }
17
+ # cache.get(:a,:b,:c,:d){ |a,b,c,d| p [a,b,c,d] }
18
+ #
19
+ # cache.get(:a,:z,:b,:y,:d){ |a,z,b,y,d| p [a,z,b,y,d] }
20
+ #
21
+ # cache.get(:missing){ |m| p [:missing=, m] }
22
+ # cache.set(:missing, 'abc'){ p :stored }
23
+ # cache.get(:missing){ |m| p [:missing=, m] }
24
+ # cache.del(:missing){ p :deleted }
25
+ # cache.get(:missing){ |m| p [:missing=, m] }
26
+ # }
27
+ #
28
+ class Memcache < TCPSocket
29
+ require 'rev_memcache/deferrable'
30
+
31
+ include Deferrable
32
+ ##
33
+ # constants
34
+
35
+ # :stopdoc:
36
+ unless defined? Cempty
37
+ Cstored = 'STORED'.freeze
38
+ Cend = 'END'.freeze
39
+ Cdeleted = 'DELETED'.freeze
40
+ Cunknown = 'NOT_FOUND'.freeze
41
+ Cerror = 'ERROR'.freeze
42
+
43
+ Cempty = ''.freeze
44
+ Cdelimiter = "\r\n".freeze
45
+ end
46
+ # :startdoc:
47
+
48
+ ##
49
+ # commands
50
+
51
+ # Get the value associated with one or multiple keys
52
+ #
53
+ # cache.get(:a){ |v| p v }
54
+ # cache.get(:a,:b,:c,:d){ |a,b,c,d| p [a,b,c,d] }
55
+ #
56
+ def get *keys
57
+ raise ArgumentError unless block_given?
58
+
59
+ callback{
60
+ keys = keys.map{|k| k.to_s.gsub(/\s/,'_') }
61
+ write "get #{keys.join(' ')}\r\n"
62
+ @get_cbs << [keys, proc{ |values|
63
+ yield *keys.map{ |k| values[k] }
64
+ }]
65
+ }
66
+ end
67
+
68
+ # Set the value for a given key
69
+ #
70
+ # cache.set :a, 'hello'
71
+ # cache.set(:missing, 'abc'){ puts "stored the value!" }
72
+ #
73
+ def set key, val, exptime = 0, &cb
74
+ callback{
75
+ val = val.to_s
76
+ send_cmd :set, key, 0, exptime, val.respond_to?(:bytesize) ? val.bytesize : val.size, !block_given?
77
+ write val
78
+ write Cdelimiter
79
+ @set_cbs << cb if cb
80
+ }
81
+ end
82
+
83
+ # Gets multiple values as a hash
84
+ #
85
+ # cache.get_hash(:a, :b, :c, :d){ |h| puts h[:a] }
86
+ #
87
+ def get_hash *keys
88
+ raise ArgumentError unless block_given?
89
+
90
+ get *keys do |*values|
91
+ yield keys.inject({}){ |hash, k| hash.update k => values[keys.index(k)] }
92
+ end
93
+ end
94
+
95
+ # Delete the value associated with a key
96
+ #
97
+ # cache.del :a
98
+ # cache.del(:b){ puts "deleted the value!" }
99
+ #
100
+ def delete key, expires = 0, &cb
101
+ callback{
102
+ write "delete #{key} #{expires}#{cb ? '' : ' noreply'}\r\n"
103
+ @del_cbs << cb if cb
104
+ }
105
+ end
106
+ alias del delete
107
+
108
+ # :stopdoc:
109
+
110
+ def send_cmd cmd, key, flags = 0, exptime = 0, bytes = 0, noreply = false # :nodoc:
111
+ write "#{cmd} #{key} #{flags} #{exptime} #{bytes}#{noreply ? ' noreply' : ''}\r\n"
112
+ end
113
+ private :send_cmd
114
+
115
+ ##
116
+ # errors
117
+
118
+ class ParserError < StandardError
119
+ end
120
+
121
+ ##
122
+ # em hooks
123
+
124
+ def on_connect
125
+ @get_cbs = []
126
+ @set_cbs = []
127
+ @del_cbs = []
128
+
129
+ @values = {}
130
+
131
+ @reconnecting = false
132
+ @connected = true
133
+ succeed
134
+ # set_delimiter "\r\n"
135
+ # set_line_mode
136
+ end
137
+
138
+ def on_read data
139
+ (@buffer||='') << data
140
+
141
+ while index = @buffer.index(Cdelimiter)
142
+ begin
143
+ line = @buffer.slice!(0,index+2)
144
+ process_cmd line
145
+ rescue ParserError
146
+ @buffer[0...0] = line
147
+ break
148
+ end
149
+ end
150
+ end
151
+
152
+ def process_cmd line
153
+ case line.strip
154
+ when /^VALUE\s+(.+?)\s+(\d+)\s+(\d+)/ # VALUE <key> <flags> <bytes>
155
+ bytes = Integer($3)
156
+ # set_binary_mode bytes+2
157
+ # @cur_key = $1
158
+ if @buffer.size >= bytes + 2
159
+ @values[$1] = @buffer.slice!(0,bytes)
160
+ @buffer.slice!(0,2) # \r\n
161
+ else
162
+ raise ParserError
163
+ end
164
+
165
+ when Cend # END
166
+ if entry = @get_cbs.shift
167
+ keys, cb = entry
168
+ cb.call(@values)
169
+ end
170
+ @values = {}
171
+
172
+ when Cstored # STORED
173
+ if cb = @set_cbs.shift
174
+ cb.call(true)
175
+ end
176
+
177
+ when Cdeleted # DELETED
178
+ if cb = @del_cbs.shift
179
+ cb.call(true)
180
+ end
181
+
182
+ when Cunknown # NOT_FOUND
183
+ if cb = @del_cbs.shift
184
+ cb.call(false)
185
+ end
186
+
187
+ else
188
+ p [:MEMCACHE_UNKNOWN, line]
189
+ end
190
+ end
191
+
192
+ def on_close
193
+ if @connected or @reconnecting
194
+ # EM.add_timer(1){ reconnect @host, @port }
195
+ @connected = false
196
+ @reconnecting = true
197
+ @deferred_status = nil
198
+ else
199
+ raise 'Unable to connect to memcached server'
200
+ end
201
+ end
202
+
203
+ # :startdoc:
204
+ end
205
+ end
@@ -0,0 +1,192 @@
1
+ #--
2
+ #
3
+ # Author:: Francis Cianfrocca (gmail: blackhedd)
4
+ # Homepage:: http://rubyeventmachine.com
5
+ # Date:: 16 Jul 2006
6
+ #
7
+ # See EventMachine and EventMachine::Connection for documentation and
8
+ # usage examples.
9
+ #
10
+ #----------------------------------------------------------------------------
11
+ #
12
+ # Copyright (C) 2006-07 by Francis Cianfrocca. All Rights Reserved.
13
+ # Gmail: blackhedd
14
+ #
15
+ # This program is free software; you can redistribute it and/or modify
16
+ # it under the terms of either: 1) the GNU General Public License
17
+ # as published by the Free Software Foundation; either version 2 of the
18
+ # License, or (at your option) any later version; or 2) Ruby's License.
19
+ #
20
+ # See the file COPYING for complete licensing information.
21
+ #
22
+ #---------------------------------------------------------------------------
23
+ #
24
+ #
25
+
26
+ module Rev
27
+ module Memcache::Deferrable
28
+
29
+ # Specify a block to be executed if and when the Deferrable object receives
30
+ # a status of :succeeded. See #set_deferred_status for more information.
31
+ #
32
+ # Calling this method on a Deferrable object whose status is not yet known
33
+ # will cause the callback block to be stored on an internal list.
34
+ # If you call this method on a Deferrable whose status is :succeeded, the
35
+ # block will be executed immediately, receiving the parameters given to the
36
+ # prior #set_deferred_status call.
37
+ #
38
+ #--
39
+ # If there is no status, add a callback to an internal list.
40
+ # If status is succeeded, execute the callback immediately.
41
+ # If status is failed, do nothing.
42
+ #
43
+ def callback &block
44
+ return unless block
45
+ @deferred_status ||= :unknown
46
+ if @deferred_status == :succeeded
47
+ block.call(*@deferred_args)
48
+ elsif @deferred_status != :failed
49
+ @callbacks ||= []
50
+ @callbacks.unshift block # << block
51
+ end
52
+ end
53
+
54
+ # Specify a block to be executed if and when the Deferrable object receives
55
+ # a status of :failed. See #set_deferred_status for more information.
56
+ #--
57
+ # If there is no status, add an errback to an internal list.
58
+ # If status is failed, execute the errback immediately.
59
+ # If status is succeeded, do nothing.
60
+ #
61
+ def errback &block
62
+ return unless block
63
+ @deferred_status ||= :unknown
64
+ if @deferred_status == :failed
65
+ block.call(*@deferred_args)
66
+ elsif @deferred_status != :succeeded
67
+ @errbacks ||= []
68
+ @errbacks.unshift block # << block
69
+ end
70
+ end
71
+
72
+ # Sets the "disposition" (status) of the Deferrable object. See also the large set of
73
+ # sugarings for this method.
74
+ # Note that if you call this method without arguments,
75
+ # no arguments will be passed to the callback/errback.
76
+ # If the user has coded these with arguments, then the
77
+ # user code will throw an argument exception.
78
+ # Implementors of deferrable classes <b>must</b>
79
+ # document the arguments they will supply to user callbacks.
80
+ #
81
+ # OBSERVE SOMETHING VERY SPECIAL here: you may call this method even
82
+ # on the INSIDE of a callback. This is very useful when a previously-registered
83
+ # callback wants to change the parameters that will be passed to subsequently-registered
84
+ # ones.
85
+ #
86
+ # You may give either :succeeded or :failed as the status argument.
87
+ #
88
+ # If you pass :succeeded, then all of the blocks passed to the object using the #callback
89
+ # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
90
+ # passed to the object using #errback will be discarded.
91
+ #
92
+ # If you pass :failed, then all of the blocks passed to the object using the #errback
93
+ # method (if any) will be executed BEFORE the #set_deferred_status method returns. All of the blocks
94
+ # passed to the object using # callback will be discarded.
95
+ #
96
+ # If you pass any arguments to #set_deferred_status in addition to the status argument,
97
+ # they will be passed as arguments to any callbacks or errbacks that are executed.
98
+ # It's your responsibility to ensure that the argument lists specified in your callbacks and
99
+ # errbacks match the arguments given in calls to #set_deferred_status, otherwise Ruby will raise
100
+ # an ArgumentError.
101
+ #
102
+ #--
103
+ # We're shifting callbacks off and discarding them as we execute them.
104
+ # This is valid because by definition callbacks are executed no more than
105
+ # once. It also has the magic effect of permitting recursive calls, which
106
+ # means that a callback can call #set_deferred_status and change the parameters
107
+ # that will be sent to subsequent callbacks down the chain.
108
+ #
109
+ # Changed @callbacks and @errbacks from push/shift to unshift/pop, per suggestion
110
+ # by Kirk Haines, to work around the memory leak bug that still exists in many Ruby
111
+ # versions.
112
+ #
113
+ # Changed 15Sep07: after processing callbacks or errbacks, CLEAR the other set of
114
+ # handlers. This gets us a little closer to the behavior of Twisted's "deferred,"
115
+ # which only allows status to be set once. Prior to making this change, it was possible
116
+ # to "succeed" a Deferrable (triggering its callbacks), and then immediately "fail" it,
117
+ # triggering its errbacks! That is clearly undesirable, but it's just as undesirable
118
+ # to raise an exception is status is set more than once on a Deferrable. The latter
119
+ # behavior would invalidate the idiom of resetting arguments by setting status from
120
+ # within a callback or errback, but more seriously it would cause spurious errors
121
+ # if a Deferrable was timed out and then an attempt was made to succeed it. See the
122
+ # comments under the new method #timeout.
123
+ #
124
+ def set_deferred_status status, *args
125
+ cancel_timeout
126
+ @errbacks ||= nil
127
+ @callbacks ||= nil
128
+ @deferred_status = status
129
+ @deferred_args = args
130
+ case @deferred_status
131
+ when :succeeded
132
+ if @callbacks
133
+ while cb = @callbacks.pop
134
+ cb.call(*@deferred_args)
135
+ end
136
+ end
137
+ @errbacks.clear if @errbacks
138
+ when :failed
139
+ if @errbacks
140
+ while eb = @errbacks.pop
141
+ eb.call(*@deferred_args)
142
+ end
143
+ end
144
+ @callbacks.clear if @callbacks
145
+ end
146
+ end
147
+
148
+
149
+ # Setting a timeout on a Deferrable causes it to go into the failed state after
150
+ # the Timeout expires (passing no arguments to the object's errbacks).
151
+ # Setting the status at any time prior to a call to the expiration of the timeout
152
+ # will cause the timer to be cancelled.
153
+ def timeout seconds
154
+ cancel_timeout
155
+ me = self
156
+ @deferred_timeout = EventMachine::Timer.new(seconds) {me.fail}
157
+ end
158
+
159
+ # Cancels an outstanding timeout if any. Undoes the action of #timeout.
160
+ #
161
+ def cancel_timeout
162
+ @deferred_timeout ||= nil
163
+ if @deferred_timeout
164
+ @deferred_timeout.cancel
165
+ @deferred_timeout = nil
166
+ end
167
+ end
168
+
169
+
170
+ # Sugar for set_deferred_status(:succeeded, ...)
171
+ #
172
+ def succeed *args
173
+ set_deferred_status :succeeded, *args
174
+ end
175
+ alias set_deferred_success succeed
176
+
177
+ # Sugar for set_deferred_status(:failed, ...)
178
+ #
179
+ def fail *args
180
+ set_deferred_status :failed, *args
181
+ end
182
+ alias set_deferred_failure fail
183
+ end
184
+
185
+
186
+ # DefaultDeferrable is an otherwise empty class that includes Deferrable.
187
+ # This is very useful when you just need to return a Deferrable object
188
+ # as a way of communicating deferred status to some other part of a program.
189
+ class Memcache::DefaultDeferrable
190
+ include Memcache::Deferrable
191
+ end
192
+ end
File without changes
@@ -0,0 +1,54 @@
1
+ # Generated by jeweler
2
+ # DO NOT EDIT THIS FILE DIRECTLY
3
+ # Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
4
+ # -*- encoding: utf-8 -*-
5
+
6
+ Gem::Specification.new do |s|
7
+ s.name = %q{rev_memcache}
8
+ s.version = "0.1.0"
9
+
10
+ s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
11
+ s.authors = ["Andrew Rudenko"]
12
+ s.date = %q{2010-02-19}
13
+ s.description = %q{Rev memcache client}
14
+ s.email = %q{ceo@prepor.ru}
15
+ s.extra_rdoc_files = [
16
+ "LICENSE",
17
+ "README.rdoc"
18
+ ]
19
+ s.files = [
20
+ ".document",
21
+ ".gitignore",
22
+ "LICENSE",
23
+ "README.rdoc",
24
+ "Rakefile",
25
+ "VERSION",
26
+ "examples/test.rb",
27
+ "lib/rev_memcache.rb",
28
+ "lib/rev_memcache/deferrable.rb",
29
+ "lib/t.rb",
30
+ "rev_memcache.gemspec"
31
+ ]
32
+ s.homepage = %q{http://github.com/prepor/rev_memcache}
33
+ s.rdoc_options = ["--charset=UTF-8"]
34
+ s.require_paths = ["lib"]
35
+ s.rubygems_version = %q{1.3.5}
36
+ s.summary = %q{Rev memcache client}
37
+ s.test_files = [
38
+ "examples/test.rb"
39
+ ]
40
+
41
+ if s.respond_to? :specification_version then
42
+ current_version = Gem::Specification::CURRENT_SPECIFICATION_VERSION
43
+ s.specification_version = 3
44
+
45
+ if Gem::Version.new(Gem::RubyGemsVersion) >= Gem::Version.new('1.2.0') then
46
+ s.add_runtime_dependency(%q<rev>, [">= 0"])
47
+ else
48
+ s.add_dependency(%q<rev>, [">= 0"])
49
+ end
50
+ else
51
+ s.add_dependency(%q<rev>, [">= 0"])
52
+ end
53
+ end
54
+
metadata ADDED
@@ -0,0 +1,75 @@
1
+ --- !ruby/object:Gem::Specification
2
+ name: rev_memcache
3
+ version: !ruby/object:Gem::Version
4
+ version: 0.1.0
5
+ platform: ruby
6
+ authors:
7
+ - Andrew Rudenko
8
+ autorequire:
9
+ bindir: bin
10
+ cert_chain: []
11
+
12
+ date: 2010-02-19 00:00:00 +03:00
13
+ default_executable:
14
+ dependencies:
15
+ - !ruby/object:Gem::Dependency
16
+ name: rev
17
+ type: :runtime
18
+ version_requirement:
19
+ version_requirements: !ruby/object:Gem::Requirement
20
+ requirements:
21
+ - - ">="
22
+ - !ruby/object:Gem::Version
23
+ version: "0"
24
+ version:
25
+ description: Rev memcache client
26
+ email: ceo@prepor.ru
27
+ executables: []
28
+
29
+ extensions: []
30
+
31
+ extra_rdoc_files:
32
+ - LICENSE
33
+ - README.rdoc
34
+ files:
35
+ - .document
36
+ - .gitignore
37
+ - LICENSE
38
+ - README.rdoc
39
+ - Rakefile
40
+ - VERSION
41
+ - examples/test.rb
42
+ - lib/rev_memcache.rb
43
+ - lib/rev_memcache/deferrable.rb
44
+ - lib/t.rb
45
+ - rev_memcache.gemspec
46
+ has_rdoc: true
47
+ homepage: http://github.com/prepor/rev_memcache
48
+ licenses: []
49
+
50
+ post_install_message:
51
+ rdoc_options:
52
+ - --charset=UTF-8
53
+ require_paths:
54
+ - lib
55
+ required_ruby_version: !ruby/object:Gem::Requirement
56
+ requirements:
57
+ - - ">="
58
+ - !ruby/object:Gem::Version
59
+ version: "0"
60
+ version:
61
+ required_rubygems_version: !ruby/object:Gem::Requirement
62
+ requirements:
63
+ - - ">="
64
+ - !ruby/object:Gem::Version
65
+ version: "0"
66
+ version:
67
+ requirements: []
68
+
69
+ rubyforge_project:
70
+ rubygems_version: 1.3.5
71
+ signing_key:
72
+ specification_version: 3
73
+ summary: Rev memcache client
74
+ test_files:
75
+ - examples/test.rb