frivol 0.1.4 → 0.1.5
Sign up to get free protection for your applications and to get access to all the features.
- data/Rakefile +1 -1
- data/VERSION +1 -1
- data/doc/classes/Frivol.html +38 -70
- data/doc/classes/Frivol.src/M000003.html +4 -4
- data/doc/classes/Frivol.src/M000004.html +3 -3
- data/doc/classes/Frivol.src/M000005.html +4 -5
- data/doc/classes/Frivol.src/M000006.html +5 -4
- data/doc/classes/Frivol.src/M000007.html +19 -0
- data/doc/classes/Frivol/ClassMethods.html +62 -26
- data/doc/classes/Frivol/ClassMethods.src/M000008.html +5 -4
- data/doc/classes/Frivol/ClassMethods.src/M000009.html +19 -0
- data/doc/classes/Frivol/ClassMethods.src/M000010.html +53 -0
- data/doc/classes/Frivol/Config.html +15 -43
- data/doc/classes/Frivol/Config.src/M000011.html +4 -5
- data/doc/classes/Frivol/Config.src/M000012.html +18 -0
- data/doc/classes/Frivol/Config.src/M000013.html +19 -0
- data/doc/classes/Time.html +4 -25
- data/doc/classes/Time.src/M000001.html +1 -1
- data/doc/classes/Time.src/M000002.html +1 -1
- data/doc/created.rid +1 -1
- data/doc/files/lib/frivol_rb.html +35 -6
- data/doc/fr_method_index.html +4 -3
- data/doc/index.html +2 -2
- data/frivol.gemspec +10 -5
- data/lib/frivol.rb +152 -32
- data/test/fake_redis.rb +5 -1
- data/test/test_frivol.rb +137 -5
- metadata +13 -8
data/lib/frivol.rb
CHANGED
@@ -28,6 +28,21 @@
|
|
28
28
|
# The <tt>expire_storage(time)</tt> method can be used to set the expiry time in seconds of the temporary storage.
|
29
29
|
# The default is not to expire the storage, in which case it will live for as long as Redis keeps it.
|
30
30
|
# <tt>delete_storage</tt>, as the name suggests will immediately delete the storage.
|
31
|
+
#
|
32
|
+
# Since version 0.1.5 Frivol can create different storage buckets. Note that this introduces a breaking change
|
33
|
+
# to the <tt>storage_key</tt> method if you have overriden it. It now takes a +bucket+ parameter.
|
34
|
+
#
|
35
|
+
# Buckets can have their own expiry time and there are special counter buckets which simply keep an integer count.
|
36
|
+
#
|
37
|
+
# storage_bucket :my_bucket, :expires_in => 5.minutes
|
38
|
+
# storage_bucket :my_counter, :counter => true
|
39
|
+
#
|
40
|
+
# Given the above, Frivol will create <tt>store_my_bucket</tt> and <tt>retrieve_my_bucket</tt> methods which work
|
41
|
+
# exactly like the standard +store+ and +retrieve+ methods. There will also be <tt>store_my_counter</tt>,
|
42
|
+
# <tt>retrieve_my_counter</tt> and <tt>increment_my_counter</tt> methods. The counter store and retrieve only
|
43
|
+
# take a integer (value and default, respectively) and the increment does not take a parameter.
|
44
|
+
#
|
45
|
+
# These methods are thread safe if you pass <tt>:thread_safe => true</tt> to the Redis configuration.
|
31
46
|
#
|
32
47
|
# Frivol uses the +storage_key+ method to create a base key for storage in Redis. The current implementation uses
|
33
48
|
# <tt>"#{self.class.name}-#{id}"</tt> so you'll want to override that method if you have classes that don't
|
@@ -44,8 +59,8 @@
|
|
44
59
|
# @key = key
|
45
60
|
# end
|
46
61
|
#
|
47
|
-
# def storage_key
|
48
|
-
# "frivol-test-#{key}" # override the storage key because we don't respond_to? id
|
62
|
+
# def storage_key(bucket = nil)
|
63
|
+
# "frivol-test-#{key}" # override the storage key because we don't respond_to? :id, and don't care about buckets
|
49
64
|
# end
|
50
65
|
#
|
51
66
|
# def big_complex_calc
|
@@ -69,6 +84,9 @@ require "redis"
|
|
69
84
|
|
70
85
|
# == Frivol
|
71
86
|
module Frivol
|
87
|
+
# Defines a constant to indicate that storage should never expire
|
88
|
+
NEVER_EXPIRE = nil
|
89
|
+
|
72
90
|
# Store a hash of keys and values.
|
73
91
|
#
|
74
92
|
# The hash need not be the complete hash of all things stored, just those you want to change.
|
@@ -77,11 +95,11 @@ module Frivol
|
|
77
95
|
# is intended to be hidden and while it is true that it currently uses a <tt>Hash#to_json</tt> you should not
|
78
96
|
# rely on this.
|
79
97
|
def store(keys_and_values)
|
80
|
-
Frivol::Helpers.retrieve_hash
|
98
|
+
hash = Frivol::Helpers.retrieve_hash(self)
|
81
99
|
keys_and_values.each do |key, value|
|
82
|
-
|
100
|
+
hash[key.to_s] = value
|
83
101
|
end
|
84
|
-
Frivol::Helpers.store_hash
|
102
|
+
Frivol::Helpers.store_hash(self, hash)
|
85
103
|
end
|
86
104
|
|
87
105
|
# Retrieve stored values, or defaults.
|
@@ -94,9 +112,9 @@ module Frivol
|
|
94
112
|
# If the default is a symbol, Frivol will attempt to get the default from a method named after that symbol.
|
95
113
|
# If the class does not <tt>respond_to?</tt> a method by that name, the symbol will assumed to be the default.
|
96
114
|
def retrieve(keys_and_defaults)
|
97
|
-
Frivol::Helpers.retrieve_hash
|
115
|
+
hash = Frivol::Helpers.retrieve_hash(self)
|
98
116
|
result = keys_and_defaults.map do |key, default|
|
99
|
-
|
117
|
+
hash[key.to_s] || (default.is_a?(Symbol) && respond_to?(default) && send(default)) || default
|
100
118
|
end
|
101
119
|
return result.first if result.size == 1
|
102
120
|
result
|
@@ -108,18 +126,22 @@ module Frivol
|
|
108
126
|
end
|
109
127
|
|
110
128
|
# Expire the stored data in +time+ seconds.
|
111
|
-
def expire_storage(time)
|
129
|
+
def expire_storage(time, bucket = nil)
|
112
130
|
return if time.nil?
|
113
|
-
Frivol::Config.redis.expire storage_key, time
|
131
|
+
Frivol::Config.redis.expire storage_key(bucket), time
|
114
132
|
end
|
115
133
|
|
116
134
|
# The base key used for storage in Redis.
|
117
135
|
#
|
118
|
-
# This method has been implemented for use with ActiveRecord and uses <tt>"#{self.class.name}-#{id}"</tt>
|
136
|
+
# This method has been implemented for use with ActiveRecord and uses <tt>"#{self.class.name}-#{id}"</tt>
|
137
|
+
# for the default bucket and <tt>"#{self.class.name}-#{id}-#{bucket}"</tt> for a named bucket.
|
119
138
|
# If you are not using ActiveRecord, or using classes that don't respond to id, you should override
|
120
139
|
# this method in your class.
|
121
|
-
|
140
|
+
#
|
141
|
+
# NOTE: This method has changed since version 0.1.4, and now has the bucket parameter (default: nil)
|
142
|
+
def storage_key(bucket = nil)
|
122
143
|
@frivol_key ||= "#{self.class.name}-#{id}"
|
144
|
+
bucket.nil? ? @frivol_key : "#{@frivol_key}-#{bucket}"
|
123
145
|
end
|
124
146
|
|
125
147
|
# == Frivol::Config
|
@@ -156,46 +178,144 @@ module Frivol
|
|
156
178
|
end
|
157
179
|
|
158
180
|
module Helpers #:nodoc:
|
159
|
-
def self.store_hash(instance)
|
160
|
-
|
161
|
-
|
162
|
-
|
181
|
+
def self.store_hash(instance, hash, bucket = nil)
|
182
|
+
data, is_new = get_hash_and_is_new(instance, bucket)
|
183
|
+
data[bucket.to_s] = hash
|
184
|
+
|
185
|
+
key = instance.send(:storage_key, bucket)
|
163
186
|
Frivol::Config.redis[key] = hash.to_json
|
164
|
-
|
165
|
-
|
166
|
-
instance.
|
187
|
+
|
188
|
+
if is_new[bucket.to_s]
|
189
|
+
time = instance.class.storage_expiry(bucket)
|
190
|
+
Frivol::Config.redis.expire(key, time) if time != Frivol::NEVER_EXPIRE
|
191
|
+
is_new[bucket.to_s] = false
|
167
192
|
end
|
168
193
|
end
|
169
194
|
|
170
|
-
def self.retrieve_hash(instance)
|
171
|
-
|
172
|
-
|
195
|
+
def self.retrieve_hash(instance, bucket = nil)
|
196
|
+
data, is_new = get_hash_and_is_new(instance, bucket)
|
197
|
+
return data[bucket.to_s] if data.key?(bucket.to_s)
|
198
|
+
key = instance.send(:storage_key, bucket)
|
173
199
|
json = Frivol::Config.redis[key]
|
174
|
-
|
200
|
+
|
201
|
+
is_new[bucket.to_s] = json.nil?
|
202
|
+
instance.instance_variable_set :@frivol_is_new, is_new
|
203
|
+
|
175
204
|
hash = json.nil? ? {} : JSON.parse(json)
|
176
|
-
|
205
|
+
data[bucket.to_s] = hash
|
206
|
+
instance.instance_variable_set :@frivol_data, data
|
207
|
+
|
177
208
|
hash
|
178
209
|
end
|
179
210
|
|
180
|
-
def self.delete_hash(instance)
|
181
|
-
key = instance.send(:storage_key)
|
211
|
+
def self.delete_hash(instance, bucket = nil)
|
212
|
+
key = instance.send(:storage_key, bucket)
|
182
213
|
Frivol::Config.redis.del key
|
183
|
-
|
214
|
+
|
215
|
+
data = instance.instance_variable_defined?(:@frivol_data) ? instance.instance_variable_get(:@frivol_data) : {}
|
216
|
+
data.delete(bucket.to_s)
|
217
|
+
instance.instance_variable_set :@frivol_data, data
|
218
|
+
end
|
219
|
+
|
220
|
+
def self.get_hash_and_is_new(instance, bucket)
|
221
|
+
data = instance.instance_variable_defined?(:@frivol_data) ? instance.instance_variable_get(:@frivol_data) : {}
|
222
|
+
is_new = instance.instance_variable_defined?(:@frivol_is_new) ? instance.instance_variable_get(:@frivol_is_new) : {}
|
223
|
+
[data, is_new]
|
224
|
+
end
|
225
|
+
|
226
|
+
def self.store_counter(instance, counter, value)
|
227
|
+
key = instance.send(:storage_key, counter)
|
228
|
+
Frivol::Config.redis[key] = value
|
229
|
+
end
|
230
|
+
|
231
|
+
def self.retrieve_counter(instance, counter, default)
|
232
|
+
key = instance.send(:storage_key, counter)
|
233
|
+
(Frivol::Config.redis[key] || default).to_i
|
234
|
+
end
|
235
|
+
|
236
|
+
def self.increment_counter(instance, counter)
|
237
|
+
key = instance.send(:storage_key, counter)
|
238
|
+
Frivol::Config.redis.incr(key)
|
184
239
|
end
|
185
240
|
end
|
186
241
|
|
187
242
|
# == Frivol::ClassMethods
|
188
243
|
# These methods are available on the class level when Frivol is included in the class.
|
189
244
|
module ClassMethods
|
190
|
-
# Set the storage expiry time in seconds.
|
191
|
-
def storage_expires_in(time)
|
192
|
-
@frivol_storage_expiry
|
245
|
+
# Set the storage expiry time in seconds for the default bucket or the bucket passed.
|
246
|
+
def storage_expires_in(time, bucket = nil)
|
247
|
+
@frivol_storage_expiry ||= {}
|
248
|
+
@frivol_storage_expiry[bucket.to_s] = time
|
193
249
|
end
|
194
250
|
|
195
|
-
# Get the storage expiry time in seconds.
|
196
|
-
def storage_expiry
|
197
|
-
@frivol_storage_expiry
|
251
|
+
# Get the storage expiry time in seconds for the default bucket or the bucket passed.
|
252
|
+
def storage_expiry(bucket = nil)
|
253
|
+
@frivol_storage_expiry ||= {}
|
254
|
+
@frivol_storage_expiry.key?(bucket.to_s) ? @frivol_storage_expiry[bucket.to_s] : NEVER_EXPIRE
|
198
255
|
end
|
256
|
+
|
257
|
+
# Create a storage bucket.
|
258
|
+
# Frivol creates store_#{bucket} and retrieve_#{bucket} methods automatically.
|
259
|
+
# These methods work exactly like the default store and retrieve methods except that the bucket is
|
260
|
+
# stored in it's own key in Redis and can have it's own expiry time.
|
261
|
+
#
|
262
|
+
# Counters are special in that they do not store a hash but only a single integer value and also
|
263
|
+
# that the data in a counter is not cached for the lifespan of the object, but rather each call
|
264
|
+
# hits Redis. This is intended to make counters thread safe (for example you may have multiple
|
265
|
+
# workers working on a job and they can each increment a progress counter which would not work
|
266
|
+
# with the default retrieve/store method that normal buckets use). For this to actually be thread safe
|
267
|
+
# you need to pass the thread safe option to the config when you make the connection.
|
268
|
+
#
|
269
|
+
# In the case of a counter, the methods work slightly differently:
|
270
|
+
# - store_#{bucket} only takes an integer value to store (no key)
|
271
|
+
# - retrieve_#{bucket} only takes an integer default, and returns only the integer value
|
272
|
+
# - there is an added increment_#{bucket} method which increments the counter by 1
|
273
|
+
#
|
274
|
+
# Options are :expires_in which sets the expiry time for a bucket,
|
275
|
+
# and :counter to create a special counter storage bucket.
|
276
|
+
def storage_bucket(bucket, options = {})
|
277
|
+
time = options[:expires_in]
|
278
|
+
storage_expires_in(time, bucket) if !time.nil?
|
279
|
+
is_counter = options[:counter]
|
280
|
+
|
281
|
+
self.class_eval do
|
282
|
+
if is_counter
|
283
|
+
define_method "store_#{bucket}" do |value|
|
284
|
+
Frivol::Helpers.store_counter(self, bucket, value)
|
285
|
+
end
|
286
|
+
|
287
|
+
define_method "retrieve_#{bucket}" do |default|
|
288
|
+
Frivol::Helpers.retrieve_counter(self, bucket, default)
|
289
|
+
end
|
290
|
+
|
291
|
+
define_method "increment_#{bucket}" do
|
292
|
+
Frivol::Helpers.increment_counter(self, bucket)
|
293
|
+
end
|
294
|
+
else
|
295
|
+
define_method "store_#{bucket}" do |keys_and_values|
|
296
|
+
hash = Frivol::Helpers.retrieve_hash(self, bucket)
|
297
|
+
keys_and_values.each do |key, value|
|
298
|
+
hash[key.to_s] = value
|
299
|
+
end
|
300
|
+
Frivol::Helpers.store_hash(self, hash, bucket)
|
301
|
+
end
|
302
|
+
|
303
|
+
define_method "retrieve_#{bucket}" do |keys_and_defaults|
|
304
|
+
hash = Frivol::Helpers.retrieve_hash(self, bucket)
|
305
|
+
result = keys_and_defaults.map do |key, default|
|
306
|
+
hash[key.to_s] || (default.is_a?(Symbol) && respond_to?(default) && send(default)) || default
|
307
|
+
end
|
308
|
+
return result.first if result.size == 1
|
309
|
+
result
|
310
|
+
end
|
311
|
+
end
|
312
|
+
end
|
313
|
+
end
|
314
|
+
|
315
|
+
# def storage_default(keys_and_defaults)
|
316
|
+
# @frivol_defaults ||= {}
|
317
|
+
# @frivol_defaults.merge keys_and_defaults
|
318
|
+
# end
|
199
319
|
end
|
200
320
|
|
201
321
|
def self.included(host) #:nodoc:
|
data/test/fake_redis.rb
CHANGED
data/test/test_frivol.rb
CHANGED
@@ -2,12 +2,12 @@ require 'helper'
|
|
2
2
|
|
3
3
|
class TestFrivol < Test::Unit::TestCase
|
4
4
|
def setup
|
5
|
-
#fake_redis # Comment out this line to test against a real live Redis
|
6
|
-
Frivol::Config.redis_config = {} # This will connect to a default Redis setup, otherwise set to { :host => "localhost", :port => 6379 }, for example
|
5
|
+
# fake_redis # Comment out this line to test against a real live Redis
|
6
|
+
Frivol::Config.redis_config = { :thread_safe => true } # This will connect to a default Redis setup, otherwise set to { :host => "localhost", :port => 6379 }, for example
|
7
7
|
end
|
8
8
|
|
9
9
|
def teardown
|
10
|
-
Frivol::Config.redis.
|
10
|
+
Frivol::Config.redis.flushdb
|
11
11
|
end
|
12
12
|
|
13
13
|
should "have a default storage key made up of the class name and id" do
|
@@ -86,7 +86,7 @@ class TestFrivol < Test::Unit::TestCase
|
|
86
86
|
|
87
87
|
should "be able to override the key method" do
|
88
88
|
class OverrideKeyTestClass < TestClass
|
89
|
-
def storage_key
|
89
|
+
def storage_key(bucket = nil)
|
90
90
|
"my_storage"
|
91
91
|
end
|
92
92
|
end
|
@@ -130,10 +130,21 @@ class TestFrivol < Test::Unit::TestCase
|
|
130
130
|
t.save
|
131
131
|
t.expire_storage 0.5
|
132
132
|
sleep 1
|
133
|
-
t = TestClass.new # Get a fresh instance so that the @
|
133
|
+
t = TestClass.new # Get a fresh instance so that the @frivol_data is empty
|
134
134
|
assert_equal "default", t.load
|
135
135
|
end
|
136
136
|
|
137
|
+
should "use default expiry set on the class" do
|
138
|
+
class ExpiryTestClass < TestClass
|
139
|
+
storage_expires_in 0.5
|
140
|
+
end
|
141
|
+
t = ExpiryTestClass.new
|
142
|
+
t.save
|
143
|
+
sleep 1
|
144
|
+
t = TestClass.new # Get a fresh instance so that the @frivol_data is empty
|
145
|
+
assert_equal "default", t.load
|
146
|
+
end
|
147
|
+
|
137
148
|
should "be able to include in other classes with storage expiry" do
|
138
149
|
class BlankTestClass
|
139
150
|
end
|
@@ -156,4 +167,125 @@ class TestFrivol < Test::Unit::TestCase
|
|
156
167
|
t.delete_storage
|
157
168
|
assert_equal "default", t.load
|
158
169
|
end
|
170
|
+
|
171
|
+
should "be able to create and use buckets" do
|
172
|
+
class SimpleBucketTestClass < TestClass
|
173
|
+
storage_bucket :blue
|
174
|
+
end
|
175
|
+
t = SimpleBucketTestClass.new
|
176
|
+
assert t.respond_to?(:store_blue)
|
177
|
+
assert t.respond_to?(:retrieve_blue)
|
178
|
+
end
|
179
|
+
|
180
|
+
should "store different values in different buckets" do
|
181
|
+
class StorageBucketTestClass < TestClass
|
182
|
+
storage_bucket :blue
|
183
|
+
|
184
|
+
def save_blue
|
185
|
+
store_blue :value => "blue value"
|
186
|
+
end
|
187
|
+
|
188
|
+
def load_blue
|
189
|
+
retrieve_blue :value => "blue default"
|
190
|
+
end
|
191
|
+
end
|
192
|
+
t = StorageBucketTestClass.new
|
193
|
+
t.save
|
194
|
+
t.save_blue
|
195
|
+
assert_equal "value", t.load
|
196
|
+
assert_equal "blue value", t.load_blue
|
197
|
+
end
|
198
|
+
|
199
|
+
should "have different expiry times for different buckets" do
|
200
|
+
class ExpireBucketsTestClass < TestClass
|
201
|
+
storage_bucket :blue, :expires_in => 0.5
|
202
|
+
storage_expires_in 2
|
203
|
+
end
|
204
|
+
t = ExpireBucketsTestClass.new
|
205
|
+
assert_equal 0.5, ExpireBucketsTestClass.storage_expiry(:blue)
|
206
|
+
assert_equal 2, ExpireBucketsTestClass.storage_expiry
|
207
|
+
end
|
208
|
+
|
209
|
+
should "expire data in buckets" do
|
210
|
+
class ExpireBucketsTestClass < TestClass
|
211
|
+
storage_bucket :blue, :expires_in => 0.5
|
212
|
+
storage_expires_in 2
|
213
|
+
|
214
|
+
def save_blue
|
215
|
+
store_blue :value => "blue value"
|
216
|
+
end
|
217
|
+
|
218
|
+
def load_blue
|
219
|
+
retrieve_blue :value => "blue default"
|
220
|
+
end
|
221
|
+
end
|
222
|
+
t = ExpireBucketsTestClass.new
|
223
|
+
t.save
|
224
|
+
t.save_blue
|
225
|
+
sleep 1
|
226
|
+
t = ExpireBucketsTestClass.new # get a new instance so @frivol_data is empty
|
227
|
+
assert_equal "value", t.load
|
228
|
+
assert_equal "blue default", t.load_blue
|
229
|
+
end
|
230
|
+
|
231
|
+
should "be able to create counter buckets" do
|
232
|
+
class SimpleCounterTestClass < TestClass
|
233
|
+
storage_bucket :blue, :counter => true
|
234
|
+
end
|
235
|
+
t = SimpleCounterTestClass.new
|
236
|
+
assert t.respond_to?(:store_blue)
|
237
|
+
assert t.respond_to?(:retrieve_blue)
|
238
|
+
assert t.respond_to?(:increment_blue)
|
239
|
+
end
|
240
|
+
|
241
|
+
should "store, increment and retrieve integers in a counter" do
|
242
|
+
class IncrCounterTestClass < TestClass
|
243
|
+
storage_bucket :blue, :counter => true
|
244
|
+
|
245
|
+
def save_blue
|
246
|
+
store_blue 10
|
247
|
+
end
|
248
|
+
|
249
|
+
def load_blue
|
250
|
+
retrieve_blue 0
|
251
|
+
end
|
252
|
+
end
|
253
|
+
t = IncrCounterTestClass.new
|
254
|
+
assert_equal 0, t.load_blue
|
255
|
+
t.save_blue
|
256
|
+
assert_equal 10, t.load_blue
|
257
|
+
assert_equal 11, t.increment_blue
|
258
|
+
assert_equal 11, t.load_blue
|
259
|
+
end
|
260
|
+
|
261
|
+
should "have thread safe counters" do
|
262
|
+
class ThreadCounterTestClass < TestClass
|
263
|
+
storage_bucket :blue, :counter => true
|
264
|
+
|
265
|
+
def save_blue
|
266
|
+
store_blue 10
|
267
|
+
end
|
268
|
+
|
269
|
+
def load_blue
|
270
|
+
retrieve_blue 0
|
271
|
+
end
|
272
|
+
end
|
273
|
+
t = ThreadCounterTestClass.new
|
274
|
+
t.save_blue
|
275
|
+
assert_equal 10, t.load_blue
|
276
|
+
|
277
|
+
threads = []
|
278
|
+
100.times do
|
279
|
+
threads << Thread.new do
|
280
|
+
10.times do
|
281
|
+
temp = ThreadCounterTestClass.new
|
282
|
+
temp.increment_blue
|
283
|
+
sleep(rand(10) / 100.0)
|
284
|
+
end
|
285
|
+
end
|
286
|
+
end
|
287
|
+
threads.each { |a| a.join }
|
288
|
+
|
289
|
+
assert_equal 1010, t.load_blue
|
290
|
+
end
|
159
291
|
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: frivol
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 17
|
5
5
|
prerelease: false
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 1
|
9
|
-
-
|
10
|
-
version: 0.1.
|
9
|
+
- 5
|
10
|
+
version: 0.1.5
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Marc Heiligers
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2010-
|
18
|
+
date: 2010-10-15 00:00:00 +02:00
|
19
19
|
default_executable:
|
20
20
|
dependencies:
|
21
21
|
- !ruby/object:Gem::Dependency
|
@@ -42,12 +42,12 @@ dependencies:
|
|
42
42
|
requirements:
|
43
43
|
- - ">="
|
44
44
|
- !ruby/object:Gem::Version
|
45
|
-
hash:
|
45
|
+
hash: 27
|
46
46
|
segments:
|
47
|
-
- 0
|
48
|
-
- 1
|
49
47
|
- 2
|
50
|
-
|
48
|
+
- 0
|
49
|
+
- 10
|
50
|
+
version: 2.0.10
|
51
51
|
type: :runtime
|
52
52
|
version_requirements: *id002
|
53
53
|
- !ruby/object:Gem::Dependency
|
@@ -87,13 +87,18 @@ files:
|
|
87
87
|
- doc/classes/Frivol.src/M000004.html
|
88
88
|
- doc/classes/Frivol.src/M000005.html
|
89
89
|
- doc/classes/Frivol.src/M000006.html
|
90
|
+
- doc/classes/Frivol.src/M000007.html
|
90
91
|
- doc/classes/Frivol/ClassMethods.html
|
91
92
|
- doc/classes/Frivol/ClassMethods.src/M000007.html
|
92
93
|
- doc/classes/Frivol/ClassMethods.src/M000008.html
|
94
|
+
- doc/classes/Frivol/ClassMethods.src/M000009.html
|
95
|
+
- doc/classes/Frivol/ClassMethods.src/M000010.html
|
93
96
|
- doc/classes/Frivol/Config.html
|
94
97
|
- doc/classes/Frivol/Config.src/M000009.html
|
95
98
|
- doc/classes/Frivol/Config.src/M000010.html
|
96
99
|
- doc/classes/Frivol/Config.src/M000011.html
|
100
|
+
- doc/classes/Frivol/Config.src/M000012.html
|
101
|
+
- doc/classes/Frivol/Config.src/M000013.html
|
97
102
|
- doc/classes/Time.html
|
98
103
|
- doc/classes/Time.src/M000001.html
|
99
104
|
- doc/classes/Time.src/M000002.html
|