gibbler 0.9.0 → 0.10.0.pre.RC1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +7 -0
- data/.github/workflows/main.yml +27 -0
- data/.github/workflows/ruby-rake.yaml +38 -0
- data/.gitignore +16 -0
- data/.pre-commit-config.yaml +60 -0
- data/.rubocop.yml +27 -0
- data/{CHANGES.txt → CHANGELOG.md} +65 -82
- data/CODE_OF_CONDUCT.md +84 -0
- data/Gemfile +16 -0
- data/LICENSE.txt +4 -2
- data/{README.rdoc → README.md} +134 -120
- data/bin/console +11 -0
- data/bin/setup +8 -0
- data/img/whoababy.gif +0 -0
- data/lib/gibbler/history.rb +39 -41
- data/lib/gibbler/mixins.rb +3 -4
- data/lib/gibbler/version.rb +17 -0
- data/lib/gibbler.rb +145 -188
- data/sig/gibbler.rbs +4 -0
- data/try/11_basic_try.rb +11 -12
- metadata +75 -27
- data/Rakefile +0 -39
- data/gibbler.gemspec +0 -71
data/lib/gibbler.rb
CHANGED
@@ -1,38 +1,24 @@
|
|
1
|
-
|
2
|
-
GIBBLER_LIB_HOME = File.expand_path File.dirname(__FILE__)
|
3
|
-
end
|
1
|
+
# frozen_string_literal: true
|
4
2
|
|
5
|
-
|
6
|
-
|
3
|
+
unless defined?(GIBBLER_LIB_HOME)
|
4
|
+
GIBBLER_LIB_HOME = File.expand_path File.dirname(__FILE__)
|
7
5
|
end
|
8
|
-
|
9
|
-
require 'thread'
|
10
|
-
require 'attic'
|
11
6
|
require 'digest/sha1'
|
12
7
|
|
13
|
-
|
14
|
-
#
|
8
|
+
|
9
|
+
# = Gibbler
|
10
|
+
#
|
15
11
|
# "Hola, Tanneritos"
|
16
12
|
#
|
17
13
|
class Gibbler < String
|
18
|
-
|
19
|
-
|
20
|
-
load_config
|
21
|
-
[@version[:MAJOR], @version[:MINOR], @version[:PATCH]].join('.')
|
22
|
-
end
|
23
|
-
alias_method :inspect, :to_s
|
24
|
-
def self.load_config
|
25
|
-
require 'yaml'
|
26
|
-
@version ||= YAML.load_file(::File.join(GIBBLER_LIB_HOME, '..', 'VERSION.yml'))
|
27
|
-
end
|
28
|
-
end
|
29
|
-
|
14
|
+
|
15
|
+
|
30
16
|
@default_base = 16
|
31
17
|
@secret = nil
|
32
18
|
class << self
|
33
19
|
attr_accessor :secret, :default_base
|
34
20
|
end
|
35
|
-
|
21
|
+
|
36
22
|
class Error < RuntimeError
|
37
23
|
def initialize(obj); @obj = obj; end
|
38
24
|
end
|
@@ -44,37 +30,37 @@ end
|
|
44
30
|
# few digest related convenience methods.
|
45
31
|
#
|
46
32
|
class Gibbler::Digest < String
|
47
|
-
|
33
|
+
|
48
34
|
module InstanceMethods
|
49
|
-
# Return an integer assuming base is Gibbler.default_base.
|
35
|
+
# Return an integer assuming base is Gibbler.default_base.
|
50
36
|
def to_i(base=nil)
|
51
37
|
base ||= Gibbler.default_base
|
52
38
|
super(base)
|
53
39
|
end
|
54
|
-
|
55
|
-
# Returns a string. Takes an optional base.
|
40
|
+
|
41
|
+
# Returns a string. Takes an optional base.
|
56
42
|
def to_s(base=nil)
|
57
43
|
base.nil? ? super() : super().to_i(Gibbler.default_base).to_s(base)
|
58
44
|
end
|
59
|
-
|
45
|
+
|
60
46
|
def base(base=Gibbler.default_base)
|
61
47
|
v = self.to_i(Gibbler.default_base).to_s(base)
|
62
48
|
v.extend Gibbler::Digest::InstanceMethods
|
63
49
|
self.class.new v
|
64
50
|
end
|
65
|
-
|
51
|
+
|
66
52
|
def base36
|
67
53
|
base(36)
|
68
54
|
end
|
69
|
-
|
70
|
-
# Shorten the digest to the given (optional) length.
|
55
|
+
|
56
|
+
# Shorten the digest to the given (optional) length.
|
71
57
|
def shorten(len=20)
|
72
58
|
self[0..len-1]
|
73
59
|
end
|
74
|
-
|
60
|
+
|
75
61
|
# Returns the first 8 characters of itself (the digest).
|
76
62
|
#
|
77
|
-
# e.g.
|
63
|
+
# e.g.
|
78
64
|
#
|
79
65
|
# "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
80
66
|
# "kimmy".gibbler.short # => c8027100
|
@@ -82,10 +68,10 @@ class Gibbler::Digest < String
|
|
82
68
|
def short
|
83
69
|
shorten(8)
|
84
70
|
end
|
85
|
-
|
71
|
+
|
86
72
|
# Returns the first 6 characters of itself (the digest).
|
87
73
|
#
|
88
|
-
# e.g.
|
74
|
+
# e.g.
|
89
75
|
#
|
90
76
|
# "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
91
77
|
# "kimmy".gibbler.shorter # => c80271
|
@@ -93,10 +79,10 @@ class Gibbler::Digest < String
|
|
93
79
|
def shorter
|
94
80
|
shorten(6)
|
95
81
|
end
|
96
|
-
|
82
|
+
|
97
83
|
# Returns the first 4 characters of itself (the digest).
|
98
84
|
#
|
99
|
-
# e.g.
|
85
|
+
# e.g.
|
100
86
|
#
|
101
87
|
# "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
102
88
|
# "kimmy".gibbler.tiny # => c802
|
@@ -104,7 +90,7 @@ class Gibbler::Digest < String
|
|
104
90
|
def tiny
|
105
91
|
shorten(4)
|
106
92
|
end
|
107
|
-
|
93
|
+
|
108
94
|
# Returns true when +ali+ matches +self+
|
109
95
|
#
|
110
96
|
# "kimmy".gibbler == "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
|
@@ -114,7 +100,7 @@ class Gibbler::Digest < String
|
|
114
100
|
return true if self.to_s == ali.to_s
|
115
101
|
false
|
116
102
|
end
|
117
|
-
|
103
|
+
|
118
104
|
# Returns true when +g+ matches one of: +self+, +short+, +shorter+, +tiny+
|
119
105
|
#
|
120
106
|
# "kimmy".gibbler === "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
|
@@ -132,32 +118,30 @@ end
|
|
132
118
|
|
133
119
|
class Gibbler < String
|
134
120
|
module Object
|
135
|
-
|
121
|
+
|
136
122
|
def self.included(obj)
|
137
123
|
obj.extend Attic
|
138
124
|
obj.attic :gibbler_cache
|
139
|
-
# Backwards compatibility for <= 0.6.2
|
140
|
-
obj.send :alias_method, :__gibbler_cache, :gibbler_cache
|
141
125
|
end
|
142
|
-
|
126
|
+
|
143
127
|
def self.gibbler_fields
|
144
128
|
end
|
145
129
|
def gibbler_fields
|
146
130
|
end
|
147
|
-
|
148
|
-
# Calculates a digest for the current object instance.
|
131
|
+
|
132
|
+
# Calculates a digest for the current object instance.
|
149
133
|
# Objects that are a kind of Hash or Array are processed
|
150
|
-
# recursively. The length of the returned String depends
|
134
|
+
# recursively. The length of the returned String depends
|
151
135
|
# on the digest type. Also stores the value in the attic.
|
152
|
-
#
|
136
|
+
#
|
153
137
|
# obj.gibbler # => a5b1191a
|
154
138
|
# obj.gibbler_cache # => a5b1191a
|
155
|
-
#
|
139
|
+
#
|
156
140
|
# Calling gibbler_cache returns the most recent digest
|
157
141
|
# without calculation.
|
158
142
|
#
|
159
143
|
# If the object is frozen, this will return the value of
|
160
|
-
#
|
144
|
+
# `gibbler_cache`.
|
161
145
|
#
|
162
146
|
def gibbler(digest_type=nil)
|
163
147
|
#gibbler_debug caller[0]
|
@@ -168,9 +152,9 @@ class Gibbler < String
|
|
168
152
|
|
169
153
|
# Has this object been modified?
|
170
154
|
#
|
171
|
-
# This method compares the return value from digest with the
|
155
|
+
# This method compares the return value from digest with the
|
172
156
|
# previous value returned by gibbler (the value is stored in
|
173
|
-
# the attic as
|
157
|
+
# the attic as `gibbler_cache`).
|
174
158
|
# See Attic[http://github.com/delano/attic]
|
175
159
|
def gibbled?
|
176
160
|
self.gibbler_cache ||= self.gibbler
|
@@ -183,15 +167,15 @@ class Gibbler < String
|
|
183
167
|
return unless Gibbler.debug?
|
184
168
|
p args
|
185
169
|
end
|
186
|
-
|
170
|
+
|
187
171
|
# Creates a digest for the current state of self based on:
|
188
172
|
# * Object#class
|
189
173
|
# * Length of Object#name || 0
|
190
174
|
# * Object#name || ''
|
191
|
-
#
|
192
|
-
# e.g. Digest::SHA1.hexdigest "Class:6:Object" #=>
|
193
175
|
#
|
194
|
-
#
|
176
|
+
# e.g. Digest::SHA1.hexdigest "Class:6:Object" #=>
|
177
|
+
#
|
178
|
+
# <b>This is a default method appropriate for only the most
|
195
179
|
# basic objects like Class and Module.</b>
|
196
180
|
#
|
197
181
|
def __gibbler(digest_type=nil)
|
@@ -202,10 +186,10 @@ class Gibbler < String
|
|
202
186
|
gibbler_debug klass, a, [klass, nom.size, nom]
|
203
187
|
a
|
204
188
|
end
|
205
|
-
|
189
|
+
|
206
190
|
# A simple override on Object#freeze to create a digest
|
207
191
|
# before the object is frozen. Once the object is frozen
|
208
|
-
#
|
192
|
+
# `obj.gibbler` will return the cached value with
|
209
193
|
# out calculation.
|
210
194
|
def freeze()
|
211
195
|
gibbler_debug :FREEZE, self.class, caller[0] if Gibbler.debug?
|
@@ -213,9 +197,9 @@ class Gibbler < String
|
|
213
197
|
super
|
214
198
|
self
|
215
199
|
end
|
216
|
-
|
200
|
+
|
217
201
|
end
|
218
|
-
|
202
|
+
|
219
203
|
end
|
220
204
|
|
221
205
|
class Gibbler < String
|
@@ -226,7 +210,7 @@ class Gibbler < String
|
|
226
210
|
# Creates a digest from the given +input+. See Gibbler.digest.
|
227
211
|
#
|
228
212
|
# If only one argument is given and it's a digest, this will
|
229
|
-
# simply create an instance of that digest. In other words,
|
213
|
+
# simply create an instance of that digest. In other words,
|
230
214
|
# it won't calculate a new digest based on that input.
|
231
215
|
def initialize *input
|
232
216
|
if input.size == 1 && Gibbler::Digest::InstanceMethods === input.first
|
@@ -235,15 +219,15 @@ class Gibbler < String
|
|
235
219
|
input.collect!(&:to_s)
|
236
220
|
super Gibbler.digest(input) || ''
|
237
221
|
end
|
238
|
-
end
|
222
|
+
end
|
239
223
|
def digest_type
|
240
224
|
@digest_type || self.class.digest_type
|
241
225
|
end
|
242
|
-
|
226
|
+
|
243
227
|
def digest *input
|
244
228
|
replace Gibbler.digest(input, digest_type)
|
245
229
|
end
|
246
|
-
|
230
|
+
|
247
231
|
end
|
248
232
|
|
249
233
|
class Gibbler < String
|
@@ -251,11 +235,11 @@ class Gibbler < String
|
|
251
235
|
@debug = false
|
252
236
|
@digest_type = ::Digest::SHA1
|
253
237
|
@delimiter = ':'
|
254
|
-
|
238
|
+
|
255
239
|
class << self
|
256
|
-
# Specify a different digest class. The default is +Digest::SHA1+. You
|
257
|
-
# could try +Digest::SHA256+ by doing this:
|
258
|
-
#
|
240
|
+
# Specify a different digest class. The default is +Digest::SHA1+. You
|
241
|
+
# could try +Digest::SHA256+ by doing this:
|
242
|
+
#
|
259
243
|
# Object.digest_type = Digest::SHA256
|
260
244
|
#
|
261
245
|
attr_accessor :digest_type
|
@@ -267,11 +251,11 @@ class Gibbler < String
|
|
267
251
|
# Returns the current debug status (true or false)
|
268
252
|
def debug?; @debug != false; end
|
269
253
|
end
|
270
|
-
|
254
|
+
|
271
255
|
# Sends +input+ to Digest::SHA1.hexdigest. If another digest class
|
272
|
-
# has been specified, that class will be used instead.
|
256
|
+
# has been specified, that class will be used instead.
|
273
257
|
# If Gibbler.secret is set, +str+ will be prepended with the
|
274
|
-
# value.
|
258
|
+
# value.
|
275
259
|
#
|
276
260
|
# If +input+ is an Array, it will be flattened and joined.
|
277
261
|
#
|
@@ -285,12 +269,12 @@ class Gibbler < String
|
|
285
269
|
dig = dig.to_i(16).to_s(Gibbler.default_base) if 16 != Gibbler.default_base
|
286
270
|
dig
|
287
271
|
end
|
288
|
-
|
272
|
+
|
289
273
|
def self.gibbler_debug(*args)
|
290
274
|
return unless Gibbler.debug?
|
291
275
|
p args
|
292
276
|
end
|
293
|
-
|
277
|
+
|
294
278
|
# Raises an exception. The correct usage is to include a Gibbler::Object:
|
295
279
|
# * Gibbler::Complex
|
296
280
|
# * Gibbler::String
|
@@ -299,20 +283,20 @@ class Gibbler < String
|
|
299
283
|
def self.included(obj)
|
300
284
|
raise "You probably want to include Gibbler::Complex or Gibbler::Object"
|
301
285
|
end
|
302
|
-
|
303
|
-
|
304
|
-
# Creates a digest based on:
|
305
|
-
# * An Array of instance variable names or method names and values in the format:
|
306
|
-
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
286
|
+
|
287
|
+
|
288
|
+
# Creates a digest based on:
|
289
|
+
# * An Array of instance variable names or method names and values in the format: `CLASS:LENGTH:VALUE`
|
290
|
+
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
307
291
|
# will be parsed recursively according to the gibbler method for that class type.
|
308
|
-
# * Digest the Array of digests
|
309
|
-
# * Return the digest for
|
292
|
+
# * Digest the Array of digests
|
293
|
+
# * Return the digest for `class:length:value` where:
|
310
294
|
# * "class" is equal to the current object class (e.g. FullHouse).
|
311
295
|
# * "length" is the size of the Array of digests (which should equal
|
312
296
|
# the number of instance variables in the object).
|
313
297
|
# * "value" is the Array of digests joined with a colon (":").
|
314
298
|
#
|
315
|
-
# This method can be used by any class which stores values in instance variables.
|
299
|
+
# This method can be used by any class which stores values in instance variables.
|
316
300
|
#
|
317
301
|
# class Episodes
|
318
302
|
# include Gibbler::Complex
|
@@ -321,7 +305,7 @@ class Gibbler < String
|
|
321
305
|
#
|
322
306
|
module Complex
|
323
307
|
include Gibbler::Object
|
324
|
-
|
308
|
+
|
325
309
|
def self.included(obj)
|
326
310
|
obj.extend Attic
|
327
311
|
obj.attic :gibbler_cache
|
@@ -343,7 +327,7 @@ class Gibbler < String
|
|
343
327
|
end
|
344
328
|
end
|
345
329
|
end
|
346
|
-
|
330
|
+
|
347
331
|
def gibbler_fields
|
348
332
|
f = [self.class.gibbler_fields].compact.flatten
|
349
333
|
if f.empty?
|
@@ -353,8 +337,8 @@ class Gibbler < String
|
|
353
337
|
end
|
354
338
|
f
|
355
339
|
end
|
356
|
-
|
357
|
-
# Creates a digest for the current state of self.
|
340
|
+
|
341
|
+
# Creates a digest for the current state of self.
|
358
342
|
def __gibbler(digest_type=nil)
|
359
343
|
klass = self.class
|
360
344
|
d = []
|
@@ -372,7 +356,7 @@ class Gibbler < String
|
|
372
356
|
gibbler_debug klass, a, [klass, d.size, d]
|
373
357
|
a
|
374
358
|
end
|
375
|
-
|
359
|
+
|
376
360
|
def __gibbler_revert!
|
377
361
|
state = self.gibbler_object self.gibbler_cache
|
378
362
|
state.instance_variables do |n|
|
@@ -381,31 +365,31 @@ class Gibbler < String
|
|
381
365
|
end
|
382
366
|
end
|
383
367
|
end
|
384
|
-
|
385
|
-
# Creates a digest based on:
|
386
|
-
# This method can be used for any class where the
|
387
|
-
# method returns an appropriate unique value for this instance.
|
388
|
-
# It's used by default for Symbol, Class,
|
368
|
+
|
369
|
+
# Creates a digest based on: `CLASS:LENGTH:VALUE`.
|
370
|
+
# This method can be used for any class where the `to_s`
|
371
|
+
# method returns an appropriate unique value for this instance.
|
372
|
+
# It's used by default for Symbol, Class, Integer.
|
389
373
|
# e.g.
|
390
|
-
#
|
374
|
+
#
|
391
375
|
# "str" => String:3:str => 509a839ca1744c72e37759e7684ff0daa3b61427
|
392
376
|
# :sym => Symbol:3:sym => f3b7b3ca9529002c6826b1ef609d3583c356c8c8
|
393
377
|
#
|
394
378
|
# To use use method in other classes simply:
|
395
379
|
#
|
396
|
-
# class MyStringLikeClass
|
380
|
+
# class MyStringLikeClass
|
397
381
|
# include Gibbler::String
|
398
382
|
# end
|
399
383
|
#
|
400
384
|
module String
|
401
385
|
include Gibbler::Object
|
402
|
-
|
386
|
+
|
403
387
|
def self.included(obj)
|
404
388
|
obj.extend Attic
|
405
389
|
obj.attic :gibbler_cache
|
406
390
|
end
|
407
|
-
|
408
|
-
# Creates a digest for the current state of self.
|
391
|
+
|
392
|
+
# Creates a digest for the current state of self.
|
409
393
|
def __gibbler(digest_type=nil)
|
410
394
|
klass = self.class
|
411
395
|
value = self.nil? ? "\0" : self.to_s
|
@@ -414,81 +398,81 @@ class Gibbler < String
|
|
414
398
|
a
|
415
399
|
end
|
416
400
|
end
|
417
|
-
|
418
|
-
# Creates a digest based on:
|
419
|
-
# * parse each key, value pair into an Array containing keys:
|
420
|
-
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
401
|
+
|
402
|
+
# Creates a digest based on:
|
403
|
+
# * parse each key, value pair into an Array containing keys: `CLASS:KEY:VALUE.__gibbler`
|
404
|
+
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
421
405
|
# will be parsed recursively according to the gibbler method for that class type.
|
422
|
-
# * Digest the Array of digests
|
423
|
-
# * Return the digest for
|
406
|
+
# * Digest the Array of digests
|
407
|
+
# * Return the digest for `class:length:value` where:
|
424
408
|
# * "class" is equal to the current object class (e.g. Hash).
|
425
409
|
# * "length" is the size of the Array of digests (which should equal
|
426
410
|
# the number of keys in the original Hash object).
|
427
411
|
# * "value" is the Array of digests joined with a colon (":").
|
428
412
|
#
|
429
|
-
# This method can be used by any class with a
|
413
|
+
# This method can be used by any class with a `keys` method.
|
430
414
|
#
|
431
415
|
# class MyOrderedHash
|
432
416
|
# include Gibbler::Hash
|
433
417
|
# end
|
434
418
|
#
|
435
|
-
module Hash
|
419
|
+
module Hash
|
436
420
|
include Gibbler::Object
|
437
|
-
|
421
|
+
|
438
422
|
def self.included(obj)
|
439
423
|
obj.extend Attic
|
440
424
|
obj.attic :gibbler_cache
|
441
425
|
end
|
442
|
-
|
443
|
-
# Creates a digest for the current state of self.
|
426
|
+
|
427
|
+
# Creates a digest for the current state of self.
|
444
428
|
def __gibbler(digest_type=nil)
|
445
429
|
klass = self.class
|
446
430
|
d = self.keys.sort { |a,b| a.inspect <=> b.inspect }
|
447
|
-
d.collect! do |name|
|
431
|
+
d.collect! do |name|
|
448
432
|
value = self[name]
|
449
433
|
unless value.respond_to? :__gibbler
|
450
434
|
gibbler_debug klass, :skipping, name
|
451
435
|
next
|
452
436
|
end
|
453
437
|
'%s:%s:%s' % [value.class, name, value.__gibbler(digest_type)]
|
454
|
-
end
|
438
|
+
end
|
455
439
|
d = d.join(Gibbler.delimiter).__gibbler(digest_type)
|
456
440
|
a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d], digest_type
|
457
441
|
gibbler_debug klass, a, [klass, d.size, d]
|
458
|
-
a
|
442
|
+
a
|
459
443
|
end
|
460
444
|
end
|
461
|
-
|
445
|
+
|
462
446
|
# Creates a digest based on:
|
463
|
-
# * parse each element into an Array of digests like:
|
464
|
-
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
465
|
-
# will be parsed recursively according to the gibbler method for that class type.
|
466
|
-
# * Digest the Array of digests
|
467
|
-
# * Return the digest for
|
447
|
+
# * parse each element into an Array of digests like: `CLASS:INDEX:VALUE.__gibbler`
|
448
|
+
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
449
|
+
# will be parsed recursively according to the gibbler method for that class type.
|
450
|
+
# * Digest the Array of digests
|
451
|
+
# * Return the digest for `class:length:value` where:
|
468
452
|
# * "class" is equal to the current object class (e.g. Array).
|
469
453
|
# * "length" is the size of the Array of digests (which should equal
|
470
454
|
# the number of elements in the original Array object).
|
471
455
|
# * "value" is the Array of digests joined with a colon (":").
|
472
456
|
#
|
473
|
-
# This method can be used by any class with an
|
457
|
+
# This method can be used by any class with an `each` method.
|
474
458
|
#
|
475
|
-
# class MyNamedArray
|
459
|
+
# class MyNamedArray
|
476
460
|
# include Gibbler::Array
|
477
461
|
# end
|
478
462
|
#
|
479
463
|
module Array
|
480
464
|
include Gibbler::Object
|
481
|
-
|
465
|
+
|
482
466
|
def self.included(obj)
|
483
467
|
obj.extend Attic
|
484
468
|
obj.attic :gibbler_cache
|
485
469
|
end
|
486
|
-
|
487
|
-
# Creates a digest for the current state of self.
|
470
|
+
|
471
|
+
# Creates a digest for the current state of self.
|
488
472
|
def __gibbler(digest_type=nil)
|
489
473
|
klass = self.class
|
490
474
|
d, index = [], 0
|
491
|
-
self.each_with_index do |value,idx|
|
475
|
+
self.each_with_index do |value,idx|
|
492
476
|
unless value.respond_to? :__gibbler
|
493
477
|
gibbler_debug klass, :skipping, idx
|
494
478
|
next
|
@@ -502,29 +486,29 @@ class Gibbler < String
|
|
502
486
|
a
|
503
487
|
end
|
504
488
|
end
|
505
|
-
|
506
|
-
# Creates a digest based on:
|
507
|
-
# Times are calculated based on the equivalent time in UTC.
|
489
|
+
|
490
|
+
# Creates a digest based on: `CLASS:LENGTH:TIME`.
|
491
|
+
# Times are calculated based on the equivalent time in UTC.
|
508
492
|
# e.g.
|
509
|
-
#
|
493
|
+
#
|
510
494
|
# Time.parse('2009-08-25 16:43:53 UTC') => 73b4635f
|
511
495
|
# Time.parse('2009-08-25 12:43:53 -04:00') => 73b4635f
|
512
496
|
#
|
513
497
|
# To use use method in other classes simply:
|
514
498
|
#
|
515
|
-
# class ClassLikeTime
|
499
|
+
# class ClassLikeTime
|
516
500
|
# include Gibbler::Time
|
517
501
|
# end
|
518
502
|
#
|
519
503
|
module Time
|
520
504
|
include Gibbler::Object
|
521
|
-
|
505
|
+
|
522
506
|
def self.included(obj)
|
523
507
|
obj.extend Attic
|
524
508
|
obj.attic :gibbler_cache
|
525
509
|
end
|
526
|
-
|
527
|
-
# Creates a digest for the current state of self.
|
510
|
+
|
511
|
+
# Creates a digest for the current state of self.
|
528
512
|
def __gibbler(digest_type=nil)
|
529
513
|
klass = self.class
|
530
514
|
value = self.nil? ? "\0" : self.utc.strftime('%Y-%m-%d %H:%M:%S UTC')
|
@@ -533,29 +517,29 @@ class Gibbler < String
|
|
533
517
|
a
|
534
518
|
end
|
535
519
|
end
|
536
|
-
|
537
|
-
# Creates a digest based on:
|
538
|
-
# Dates are calculated based on the equivalent datetime in UTC.
|
520
|
+
|
521
|
+
# Creates a digest based on: `CLASS:LENGTH:DATETIME`.
|
522
|
+
# Dates are calculated based on the equivalent datetime in UTC.
|
539
523
|
# e.g.
|
540
|
-
#
|
524
|
+
#
|
541
525
|
# DateTime.parse('2009-08-25T17:00:40+00:00') => ad64c769
|
542
526
|
# DateTime.parse('2009-08-25T13:00:40-04:00') => ad64c769
|
543
527
|
#
|
544
528
|
# To use use method in other classes simply:
|
545
529
|
#
|
546
|
-
# class ClassLikeTime
|
530
|
+
# class ClassLikeTime
|
547
531
|
# include Gibbler::Time
|
548
532
|
# end
|
549
533
|
#
|
550
534
|
module DateTime
|
551
535
|
include Gibbler::Object
|
552
|
-
|
536
|
+
|
553
537
|
def self.included(obj)
|
554
538
|
obj.extend Attic
|
555
539
|
obj.attic :gibbler_cache
|
556
540
|
end
|
557
|
-
|
558
|
-
# Creates a digest for the current state of self.
|
541
|
+
|
542
|
+
# Creates a digest for the current state of self.
|
559
543
|
def __gibbler(digest_type=nil)
|
560
544
|
klass = self.class
|
561
545
|
value = self.nil? ? "\0" : self.new_offset(0).to_s
|
@@ -563,36 +547,36 @@ class Gibbler < String
|
|
563
547
|
gibbler_debug klass, a, [klass, value.size, value]
|
564
548
|
a
|
565
549
|
end
|
566
|
-
|
550
|
+
|
567
551
|
end
|
568
|
-
|
569
|
-
# Creates a digest based on:
|
552
|
+
|
553
|
+
# Creates a digest based on: `CLASS:EXCLUDE?:FIRST:LAST`
|
570
554
|
# where EXCLUDE? is a boolean value whether the Range excludes
|
571
555
|
# the last value (i.e. 1...100) and FIRST and LAST are the values
|
572
556
|
# returned by Range#first and Range#last.
|
573
557
|
# e.g.
|
574
|
-
#
|
558
|
+
#
|
575
559
|
# (1..100) => Range:false:1:100 => 54506352
|
576
560
|
# (1...100) => Range:true:1:100 => f0cad8cc
|
577
561
|
#
|
578
562
|
# To use use method in other classes simply:
|
579
563
|
#
|
580
|
-
# class ClassLikeRange
|
564
|
+
# class ClassLikeRange
|
581
565
|
# include Gibbler::Range
|
582
566
|
# end
|
583
567
|
#
|
584
568
|
module Range
|
585
569
|
include Gibbler::Object
|
586
|
-
|
570
|
+
|
587
571
|
def self.included(obj)
|
588
572
|
obj.extend Attic
|
589
573
|
obj.attic :gibbler_cache
|
590
574
|
end
|
591
|
-
|
592
|
-
# Creates a digest for the current state of self.
|
575
|
+
|
576
|
+
# Creates a digest for the current state of self.
|
593
577
|
def __gibbler(digest_type=nil)
|
594
578
|
klass = self.class
|
595
|
-
if self.nil?
|
579
|
+
if self.nil?
|
596
580
|
first, last, exclude = "\0", "\0", "\0"
|
597
581
|
else
|
598
582
|
first, last, exclude = self.first, self.last, self.exclude_end?
|
@@ -601,10 +585,10 @@ class Gibbler < String
|
|
601
585
|
gibbler_debug klass, a, [klass, exclude, first, last]
|
602
586
|
a
|
603
587
|
end
|
604
|
-
|
588
|
+
|
605
589
|
end
|
606
|
-
|
607
|
-
# Creates a digest based on:
|
590
|
+
|
591
|
+
# Creates a digest based on: `CLASS:\0`
|
608
592
|
#
|
609
593
|
# e.g.
|
610
594
|
#
|
@@ -618,7 +602,7 @@ class Gibbler < String
|
|
618
602
|
obj.attic :gibbler_cache
|
619
603
|
end
|
620
604
|
|
621
|
-
# Creates a digest for the current state of self.
|
605
|
+
# Creates a digest for the current state of self.
|
622
606
|
def __gibbler(digest_type=nil)
|
623
607
|
klass = self.class
|
624
608
|
a = Gibbler.digest "%s:%s" % [klass, "\0"], digest_type
|
@@ -626,34 +610,34 @@ class Gibbler < String
|
|
626
610
|
a
|
627
611
|
end
|
628
612
|
end
|
629
|
-
|
630
|
-
# Creates a digest based on:
|
613
|
+
|
614
|
+
# Creates a digest based on: `CLASS:PATHLENGTH:PATH`
|
631
615
|
# where PATHLENGTH is the length of the PATH string. PATH is
|
632
616
|
# not modified in any way (it is not converted to an absolute
|
633
|
-
# path).
|
634
|
-
#
|
617
|
+
# path).
|
618
|
+
#
|
635
619
|
# NOTE: You may expect this method to include other information
|
636
620
|
# like the file contents and modified date (etc...). The reason
|
637
621
|
# we do not is because Gibbler is concerned only about Ruby and
|
638
622
|
# not the outside world. There are many complexities in parsing
|
639
623
|
# file data and attributes which would make it difficult to run
|
640
|
-
# across platforms and Ruby versions / engines. If you want to
|
624
|
+
# across platforms and Ruby versions / engines. If you want to
|
641
625
|
#
|
642
626
|
# e.g.
|
643
|
-
#
|
627
|
+
#
|
644
628
|
# File.new('.') # => c8bc8b3a
|
645
629
|
# File.new('/tmp') # => 3af85a19
|
646
630
|
# File.new('/tmp/') # => 92cbcb7d
|
647
|
-
#
|
631
|
+
#
|
648
632
|
module File
|
649
633
|
include Gibbler::Object
|
650
|
-
|
634
|
+
|
651
635
|
def self.included(obj)
|
652
636
|
obj.extend Attic
|
653
637
|
obj.attic :gibbler_cache
|
654
638
|
end
|
655
|
-
|
656
|
-
# Creates a digest for the current state of self.
|
639
|
+
|
640
|
+
# Creates a digest for the current state of self.
|
657
641
|
def __gibbler(digest_type=nil)
|
658
642
|
klass = self.class
|
659
643
|
value = self.nil? ? "\0" : self.path
|
@@ -662,29 +646,7 @@ class Gibbler < String
|
|
662
646
|
a
|
663
647
|
end
|
664
648
|
end
|
665
|
-
|
666
|
-
##--
|
667
|
-
## NOTE: this was used when Gibbler supported "include Gibbler". We
|
668
|
-
## now recommend the "include Gibbler::String" approach. This was an
|
669
|
-
## interesting approach so I'm keeping the code here for reference.
|
670
|
-
##def self.included(klass)
|
671
|
-
## # Find the appropriate Gibbler::* module for the inheriting class
|
672
|
-
## gibbler_module = Gibbler.const_get("#{klass}") rescue Gibbler::String
|
673
|
-
##
|
674
|
-
## # If a Gibbler module is not defined, const_get bubbles up
|
675
|
-
## # through the stack to find the constant. This will return
|
676
|
-
## # the global class (likely itself) so we enforce a default.
|
677
|
-
## gibbler_module = Gibbler::String if gibbler_module == klass
|
678
|
-
## gibbler_debug :constant, klass, gibbler_module
|
679
|
-
##
|
680
|
-
## klass.module_eval do
|
681
|
-
## include gibbler_module
|
682
|
-
## end
|
683
|
-
##
|
684
|
-
##end
|
685
|
-
##++
|
686
|
-
|
687
|
-
|
649
|
+
|
688
650
|
end
|
689
651
|
|
690
652
|
class String
|
@@ -694,8 +656,3 @@ class String
|
|
694
656
|
end
|
695
657
|
end
|
696
658
|
end
|
697
|
-
|
698
|
-
|
699
|
-
|
700
|
-
|
701
|
-
|