mini_cache 1.0.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 +17 -0
- data/Gemfile +4 -0
- data/LICENSE +22 -0
- data/README.md +150 -0
- data/Rakefile +12 -0
- data/lib/mini_cache/store.rb +145 -0
- data/lib/mini_cache/version.rb +3 -0
- data/lib/mini_cache.rb +2 -0
- data/mini_cache.gemspec +19 -0
- data/test/mini_cache/store_test.rb +138 -0
- data/test/test_helper.rb +4 -0
- metadata +76 -0
data/.gitignore
ADDED
data/Gemfile
ADDED
data/LICENSE
ADDED
@@ -0,0 +1,22 @@
|
|
1
|
+
Copyright (c) 2012 Derrick Reimer
|
2
|
+
|
3
|
+
MIT License
|
4
|
+
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
6
|
+
a copy of this software and associated documentation files (the
|
7
|
+
"Software"), to deal in the Software without restriction, including
|
8
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
9
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
10
|
+
permit persons to whom the Software is furnished to do so, subject to
|
11
|
+
the following conditions:
|
12
|
+
|
13
|
+
The above copyright notice and this permission notice shall be
|
14
|
+
included in all copies or substantial portions of the Software.
|
15
|
+
|
16
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
17
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
18
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
19
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
20
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
21
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
22
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/README.md
ADDED
@@ -0,0 +1,150 @@
|
|
1
|
+
# MiniCache
|
2
|
+
|
3
|
+
MiniCache is a lightweight in-memory key-value store for Ruby objects.
|
4
|
+
This gem has no external dependencies and can be used in a Ruby project
|
5
|
+
(including Rails apps).
|
6
|
+
|
7
|
+
## Motivation
|
8
|
+
|
9
|
+
It is common practice to cache certain values on an object that are
|
10
|
+
computationally expensive to obtain, such as a property that requires a
|
11
|
+
database query.
|
12
|
+
|
13
|
+
The simplest way to do this is by storing the value in an instance variable:
|
14
|
+
|
15
|
+
```ruby
|
16
|
+
class Account
|
17
|
+
def calculate_balance
|
18
|
+
# Do something expensive.
|
19
|
+
end
|
20
|
+
|
21
|
+
def balance
|
22
|
+
@balance ||= self.calculate_balance
|
23
|
+
end
|
24
|
+
end
|
25
|
+
```
|
26
|
+
|
27
|
+
While this method works in many scenarios, it fails when the value you
|
28
|
+
need to cache is:
|
29
|
+
|
30
|
+
- Either `nil` or `false`
|
31
|
+
- Dependent on a particular argument passed to the method
|
32
|
+
|
33
|
+
Here's a demonstration of how MiniCache solves this problem:
|
34
|
+
|
35
|
+
```ruby
|
36
|
+
class Account
|
37
|
+
def lookup_role(user)
|
38
|
+
# Execute a database query to find the user's role.
|
39
|
+
end
|
40
|
+
|
41
|
+
def role(user)
|
42
|
+
# Perform the lookup once and cache the value. We can't use
|
43
|
+
#
|
44
|
+
# @role ||= lookup_user(user)
|
45
|
+
#
|
46
|
+
# because the value depends on the user argument. Also, the
|
47
|
+
# value could be nil if the user does not actually have a role.
|
48
|
+
# You can probably see how the solution could get pretty ugly.
|
49
|
+
# This is where MiniCache comes into play.
|
50
|
+
self.cache.get_or_set("role-#{user.id}") do
|
51
|
+
self.lookup_role(user)
|
52
|
+
end
|
53
|
+
end
|
54
|
+
|
55
|
+
def cache
|
56
|
+
@cache ||= MiniCache::Store.new
|
57
|
+
end
|
58
|
+
end
|
59
|
+
```
|
60
|
+
|
61
|
+
The `#get_or_set` method works similarly to the `||=` operator, except it
|
62
|
+
knows how to handle `false` and `nil` values and it's keyed off of a unique string ID.
|
63
|
+
Problem solved!
|
64
|
+
|
65
|
+
## Installation
|
66
|
+
|
67
|
+
Add this line to your application's Gemfile:
|
68
|
+
|
69
|
+
gem 'mini_cache'
|
70
|
+
|
71
|
+
And then execute:
|
72
|
+
|
73
|
+
$ bundle
|
74
|
+
|
75
|
+
Or install it yourself as:
|
76
|
+
|
77
|
+
$ gem install mini_cache
|
78
|
+
|
79
|
+
## Usage
|
80
|
+
|
81
|
+
To create a new MiniCache store object, just initialize it:
|
82
|
+
|
83
|
+
```ruby
|
84
|
+
store = MiniCache::Store.new
|
85
|
+
|
86
|
+
# Optionally pass in a Hash of data
|
87
|
+
store = MiniCache::Store.new(:name => "Derrick", :occupation => "Developer")
|
88
|
+
```
|
89
|
+
|
90
|
+
Set and retrieve data using `#get` and `#set`:
|
91
|
+
|
92
|
+
```ruby
|
93
|
+
# Pass in the value as an argument or block
|
94
|
+
store.set("age", 24)
|
95
|
+
store.set("birth_year") { 1988 }
|
96
|
+
|
97
|
+
store.get("birth_year")
|
98
|
+
=> 1988
|
99
|
+
```
|
100
|
+
|
101
|
+
Use the `#get_or_set` method to either set the value if it hasn't already been
|
102
|
+
set, or get the value that was already set.
|
103
|
+
|
104
|
+
```ruby
|
105
|
+
store.set("birth_year") { 1988 }
|
106
|
+
=> 1988
|
107
|
+
|
108
|
+
store.get_or_set("birth_year") { 1964 }
|
109
|
+
=> 1988 # Did not overwrite previously set value
|
110
|
+
```
|
111
|
+
|
112
|
+
Other convenience methods:
|
113
|
+
|
114
|
+
- `#set?(key)`: Checks to see if a value has been set for a given key
|
115
|
+
- `#unset(key)`: Removes a key-value pair for a given key.
|
116
|
+
- `#reset`: Clears the cache.
|
117
|
+
- `#load(hash)`: Loads a hash of data into the cache (appended to existing data).
|
118
|
+
|
119
|
+
## Contributing
|
120
|
+
|
121
|
+
1. Fork it
|
122
|
+
2. Create your feature branch (`git checkout -b my-new-feature`)
|
123
|
+
3. Commit your changes (`git commit -am 'Added some feature'`)
|
124
|
+
4. Push to the branch (`git push origin my-new-feature`)
|
125
|
+
5. Create new Pull Request
|
126
|
+
|
127
|
+
## License
|
128
|
+
|
129
|
+
Copyright © 2012 Derrick Reimer
|
130
|
+
|
131
|
+
MIT License
|
132
|
+
|
133
|
+
Permission is hereby granted, free of charge, to any person obtaining
|
134
|
+
a copy of this software and associated documentation files (the
|
135
|
+
"Software"), to deal in the Software without restriction, including
|
136
|
+
without limitation the rights to use, copy, modify, merge, publish,
|
137
|
+
distribute, sublicense, and/or sell copies of the Software, and to
|
138
|
+
permit persons to whom the Software is furnished to do so, subject to
|
139
|
+
the following conditions:
|
140
|
+
|
141
|
+
The above copyright notice and this permission notice shall be
|
142
|
+
included in all copies or substantial portions of the Software.
|
143
|
+
|
144
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
145
|
+
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
146
|
+
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
147
|
+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
|
148
|
+
LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
149
|
+
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
|
150
|
+
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
data/Rakefile
ADDED
@@ -0,0 +1,145 @@
|
|
1
|
+
module MiniCache
|
2
|
+
class Store
|
3
|
+
include Enumerable
|
4
|
+
|
5
|
+
# Public: Returns the hash of key-value pairs.
|
6
|
+
attr_reader :data
|
7
|
+
|
8
|
+
# Public: Initializes a new TinyCache object.
|
9
|
+
#
|
10
|
+
# data - A Hash of key-value pairs (optional).
|
11
|
+
#
|
12
|
+
# Returns nothing.
|
13
|
+
def initialize(data = {})
|
14
|
+
@data = {}
|
15
|
+
self.load(data)
|
16
|
+
end
|
17
|
+
|
18
|
+
# Public: Retrieves the value for a given key.
|
19
|
+
#
|
20
|
+
# key - A String or Symbol representing the key.
|
21
|
+
#
|
22
|
+
# Returns the value set for the key; if nothing is
|
23
|
+
# set, returns nil.
|
24
|
+
def get(key)
|
25
|
+
check_key!(key)
|
26
|
+
@data[key.to_s]
|
27
|
+
end
|
28
|
+
|
29
|
+
# Public: Sets a value for a given key either as
|
30
|
+
# an argument or block.
|
31
|
+
#
|
32
|
+
# key - A String or Symbol representing the key.
|
33
|
+
# value - Any object that represents the value (optional).
|
34
|
+
# Not used if a block is given.
|
35
|
+
# block - A block of code that returns the value to set
|
36
|
+
# (optional).
|
37
|
+
#
|
38
|
+
# Examples
|
39
|
+
#
|
40
|
+
# cache.set("name", "Derrick")
|
41
|
+
# => "Derrick"
|
42
|
+
#
|
43
|
+
# cache.set("name") { "Joe" }
|
44
|
+
# => "Joe"
|
45
|
+
#
|
46
|
+
# Returns the value given.
|
47
|
+
def set(key, value = nil)
|
48
|
+
check_key!(key)
|
49
|
+
@data[key.to_s] = block_given? ? yield : value
|
50
|
+
end
|
51
|
+
|
52
|
+
# Public: Determines whether a value has been set for
|
53
|
+
# a given key.
|
54
|
+
#
|
55
|
+
# key - A String or Symbol representing the key.
|
56
|
+
#
|
57
|
+
# Returns a Boolean.
|
58
|
+
def set?(key)
|
59
|
+
check_key!(key)
|
60
|
+
@data.keys.include?(key.to_s)
|
61
|
+
end
|
62
|
+
|
63
|
+
# Public: Retrieves the value for a given key if it
|
64
|
+
# has already been set; otherwise, sets the value
|
65
|
+
# either as an argument or block.
|
66
|
+
#
|
67
|
+
# key - A String or Symbol representing the key.
|
68
|
+
# value - Any object that represents the value (optional).
|
69
|
+
# Not used if a block is given.
|
70
|
+
# block - A block of code that returns the value to set
|
71
|
+
# (optional).
|
72
|
+
#
|
73
|
+
# Examples
|
74
|
+
#
|
75
|
+
# cache.set("name", "Derrick")
|
76
|
+
# => "Derrick"
|
77
|
+
#
|
78
|
+
# cache.get_or_set("name", "Joe")
|
79
|
+
# => "Derrick"
|
80
|
+
#
|
81
|
+
# cache.get_or_set("occupation") { "Engineer" }
|
82
|
+
# => "Engineer"
|
83
|
+
#
|
84
|
+
# cache.get_or_set("occupation") { "Pilot" }
|
85
|
+
# => "Engineer"
|
86
|
+
#
|
87
|
+
# Returns the value.
|
88
|
+
def get_or_set(key, value = nil)
|
89
|
+
return get(key) if set?(key)
|
90
|
+
set(key, block_given? ? yield : value)
|
91
|
+
end
|
92
|
+
|
93
|
+
# Public: Removes the key-value pair from the cache
|
94
|
+
# for a given key.
|
95
|
+
#
|
96
|
+
# key - A String or Symbol representing the key.
|
97
|
+
#
|
98
|
+
# Returns the value.
|
99
|
+
def unset(key)
|
100
|
+
check_key!(key)
|
101
|
+
@data.delete(key.to_s)
|
102
|
+
end
|
103
|
+
|
104
|
+
# Public: Clears all key-value pairs.
|
105
|
+
#
|
106
|
+
# Returns nothing.
|
107
|
+
def reset
|
108
|
+
@data = {}
|
109
|
+
end
|
110
|
+
|
111
|
+
# Public: Iterates over all key-value pairs.
|
112
|
+
#
|
113
|
+
# block - A block of code that will be send the key
|
114
|
+
# and value of each pair.
|
115
|
+
#
|
116
|
+
# Yields the String key and value.
|
117
|
+
def each(&block)
|
118
|
+
@data.each { |k, v| yield(k, v) }
|
119
|
+
end
|
120
|
+
|
121
|
+
# Public: Loads a hash of data into the cache.
|
122
|
+
#
|
123
|
+
# data - A Hash of data with either String or Symbol keys.
|
124
|
+
#
|
125
|
+
# Returns nothing.
|
126
|
+
def load(data)
|
127
|
+
data.each do |key, value|
|
128
|
+
check_key!(key)
|
129
|
+
@data[key.to_s] = value
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
133
|
+
private
|
134
|
+
|
135
|
+
# Internal: Raises an error if the key is not a String
|
136
|
+
# or a Symbol.
|
137
|
+
#
|
138
|
+
# key - A key provided by the user.
|
139
|
+
def check_key!(key)
|
140
|
+
unless key.is_a?(String) || key.is_a?(Symbol)
|
141
|
+
raise TypeError, "key must be a String or Symbol"
|
142
|
+
end
|
143
|
+
end
|
144
|
+
end
|
145
|
+
end
|
data/lib/mini_cache.rb
ADDED
data/mini_cache.gemspec
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
# -*- encoding: utf-8 -*-
|
2
|
+
require File.expand_path('../lib/mini_cache/version', __FILE__)
|
3
|
+
|
4
|
+
Gem::Specification.new do |gem|
|
5
|
+
gem.authors = ["Derrick Reimer"]
|
6
|
+
gem.email = ["derrickreimer@gmail.com"]
|
7
|
+
gem.description = %q{A lightweight, in-memory cache for Ruby objects}
|
8
|
+
gem.summary = %q{MiniCache is a lightweight, in-memory key-value store for Ruby objects}
|
9
|
+
gem.homepage = "https://github.com/djreimer/mini_cache"
|
10
|
+
|
11
|
+
gem.files = `git ls-files`.split($\)
|
12
|
+
gem.executables = gem.files.grep(%r{^bin/}).map{ |f| File.basename(f) }
|
13
|
+
gem.test_files = gem.files.grep(%r{^(test|spec|features)/})
|
14
|
+
gem.name = "mini_cache"
|
15
|
+
gem.require_paths = ["lib"]
|
16
|
+
gem.version = MiniCache::VERSION
|
17
|
+
|
18
|
+
gem.add_development_dependency "shoulda-context"
|
19
|
+
end
|
@@ -0,0 +1,138 @@
|
|
1
|
+
require File.dirname(__FILE__) + '/../test_helper.rb'
|
2
|
+
|
3
|
+
class MiniCache::StoreTest < Test::Unit::TestCase
|
4
|
+
def setup
|
5
|
+
@store = MiniCache::Store.new
|
6
|
+
end
|
7
|
+
|
8
|
+
context "initialize" do
|
9
|
+
should "default to empty data" do
|
10
|
+
store = MiniCache::Store.new
|
11
|
+
assert_equal Hash.new, store.data
|
12
|
+
end
|
13
|
+
|
14
|
+
should "load seed data" do
|
15
|
+
data = { "name" => "Derrick" }
|
16
|
+
store = MiniCache::Store.new(data)
|
17
|
+
assert_equal data, store.data
|
18
|
+
end
|
19
|
+
end
|
20
|
+
|
21
|
+
context "#get" do
|
22
|
+
should "return a value if set" do
|
23
|
+
@store.set("name", "Derrick")
|
24
|
+
assert_equal "Derrick", @store.get("name")
|
25
|
+
end
|
26
|
+
|
27
|
+
should "return nil if not set" do
|
28
|
+
assert_nil @store.get("name")
|
29
|
+
end
|
30
|
+
|
31
|
+
should "raise a TypeError if key is not valid" do
|
32
|
+
assert_raises(TypeError) { @store.get([1, 2]) }
|
33
|
+
end
|
34
|
+
end
|
35
|
+
|
36
|
+
context "#set" do
|
37
|
+
should "accept the value as an argument" do
|
38
|
+
@store.set("name", "Derrick")
|
39
|
+
assert_equal "Derrick", @store.get("name")
|
40
|
+
end
|
41
|
+
|
42
|
+
should "accept the value as a block" do
|
43
|
+
@store.set("name") { "Derrick" }
|
44
|
+
assert_equal "Derrick", @store.get("name")
|
45
|
+
end
|
46
|
+
|
47
|
+
should "raise a TypeError if key is not valid" do
|
48
|
+
assert_raises(TypeError) { @store.set([1, 2], "foo") }
|
49
|
+
end
|
50
|
+
end
|
51
|
+
|
52
|
+
context "#set?" do
|
53
|
+
should "be true if key has been set" do
|
54
|
+
@store.set("name", "Derrick")
|
55
|
+
assert_equal true, @store.set?("name")
|
56
|
+
end
|
57
|
+
|
58
|
+
should "be false if key has not been set" do
|
59
|
+
assert_equal false, @store.set?("foobar")
|
60
|
+
end
|
61
|
+
|
62
|
+
should "raise a TypeError if key is not valid" do
|
63
|
+
assert_raises(TypeError) { @store.set?([1, 2]) }
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
context "#get_or_set" do
|
68
|
+
should "set the value if it hasn't already been set" do
|
69
|
+
@store.get_or_set("name", "Derrick")
|
70
|
+
assert_equal "Derrick", @store.get("name")
|
71
|
+
end
|
72
|
+
|
73
|
+
should "not set the value if it has already been set" do
|
74
|
+
@store.set("name", "Derrick")
|
75
|
+
@store.get_or_set("name", "Joe")
|
76
|
+
assert_equal "Derrick", @store.get("name")
|
77
|
+
end
|
78
|
+
|
79
|
+
should "return the value if not already set" do
|
80
|
+
assert_equal "Derrick", @store.get_or_set("name", "Derrick")
|
81
|
+
end
|
82
|
+
|
83
|
+
should "return the value if already set" do
|
84
|
+
@store.set("name", "Derrick")
|
85
|
+
assert_equal "Derrick", @store.get_or_set("name", "Joe")
|
86
|
+
end
|
87
|
+
|
88
|
+
should "accept the value as a block" do
|
89
|
+
@store.get_or_set("name") { "Joe" }
|
90
|
+
assert_equal "Joe", @store.get("name")
|
91
|
+
end
|
92
|
+
|
93
|
+
should "raise a TypeError if key is not valid" do
|
94
|
+
assert_raises(TypeError) { @store.get_or_set([1, 2], "foo") }
|
95
|
+
end
|
96
|
+
end
|
97
|
+
|
98
|
+
context "#unset" do
|
99
|
+
should "remove the key-value pair" do
|
100
|
+
@store.set("name", "Derrick")
|
101
|
+
@store.unset("name")
|
102
|
+
assert !@store.data.keys.include?("name")
|
103
|
+
end
|
104
|
+
end
|
105
|
+
|
106
|
+
context "#reset" do
|
107
|
+
should "remove all data" do
|
108
|
+
@store.set("name", "Derrick")
|
109
|
+
@store.reset
|
110
|
+
assert_equal Hash.new, @store.data
|
111
|
+
end
|
112
|
+
end
|
113
|
+
|
114
|
+
context "#load" do
|
115
|
+
should "append the data to the cache" do
|
116
|
+
@store.set("title", "Mr.")
|
117
|
+
|
118
|
+
data = { "name" => "Derrick", "occupation" => "Developer" }
|
119
|
+
@store.load(data)
|
120
|
+
|
121
|
+
all_data = { "title" => "Mr.",
|
122
|
+
"name" => "Derrick", "occupation" => "Developer" }
|
123
|
+
assert_equal all_data, @store.data
|
124
|
+
end
|
125
|
+
|
126
|
+
should "stringify the keys" do
|
127
|
+
data = { :name => "Derrick" }
|
128
|
+
@store.load(data)
|
129
|
+
stringified_data = { "name" => "Derrick" }
|
130
|
+
assert_equal stringified_data, @store.data
|
131
|
+
end
|
132
|
+
|
133
|
+
should "raise a TypeError if an invalid key is encountered" do
|
134
|
+
data = { [1, 2] => "Derrick" }
|
135
|
+
assert_raises(TypeError) { @store.load(data) }
|
136
|
+
end
|
137
|
+
end
|
138
|
+
end
|
data/test/test_helper.rb
ADDED
metadata
ADDED
@@ -0,0 +1,76 @@
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
|
+
name: mini_cache
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
prerelease:
|
5
|
+
version: 1.0.0
|
6
|
+
platform: ruby
|
7
|
+
authors:
|
8
|
+
- Derrick Reimer
|
9
|
+
autorequire:
|
10
|
+
bindir: bin
|
11
|
+
cert_chain: []
|
12
|
+
|
13
|
+
date: 2012-07-21 00:00:00 Z
|
14
|
+
dependencies:
|
15
|
+
- !ruby/object:Gem::Dependency
|
16
|
+
name: shoulda-context
|
17
|
+
prerelease: false
|
18
|
+
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
+
none: false
|
20
|
+
requirements:
|
21
|
+
- - ">="
|
22
|
+
- !ruby/object:Gem::Version
|
23
|
+
version: "0"
|
24
|
+
type: :development
|
25
|
+
version_requirements: *id001
|
26
|
+
description: A lightweight, in-memory cache for Ruby objects
|
27
|
+
email:
|
28
|
+
- derrickreimer@gmail.com
|
29
|
+
executables: []
|
30
|
+
|
31
|
+
extensions: []
|
32
|
+
|
33
|
+
extra_rdoc_files: []
|
34
|
+
|
35
|
+
files:
|
36
|
+
- .gitignore
|
37
|
+
- Gemfile
|
38
|
+
- LICENSE
|
39
|
+
- README.md
|
40
|
+
- Rakefile
|
41
|
+
- lib/mini_cache.rb
|
42
|
+
- lib/mini_cache/store.rb
|
43
|
+
- lib/mini_cache/version.rb
|
44
|
+
- mini_cache.gemspec
|
45
|
+
- test/mini_cache/store_test.rb
|
46
|
+
- test/test_helper.rb
|
47
|
+
homepage: https://github.com/djreimer/mini_cache
|
48
|
+
licenses: []
|
49
|
+
|
50
|
+
post_install_message:
|
51
|
+
rdoc_options: []
|
52
|
+
|
53
|
+
require_paths:
|
54
|
+
- lib
|
55
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
56
|
+
none: false
|
57
|
+
requirements:
|
58
|
+
- - ">="
|
59
|
+
- !ruby/object:Gem::Version
|
60
|
+
version: "0"
|
61
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
62
|
+
none: false
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: "0"
|
67
|
+
requirements: []
|
68
|
+
|
69
|
+
rubyforge_project:
|
70
|
+
rubygems_version: 1.8.24
|
71
|
+
signing_key:
|
72
|
+
specification_version: 3
|
73
|
+
summary: MiniCache is a lightweight, in-memory key-value store for Ruby objects
|
74
|
+
test_files:
|
75
|
+
- test/mini_cache/store_test.rb
|
76
|
+
- test/test_helper.rb
|