gibbler 0.9.0 → 0.10.0.pre.RC1
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.
- 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
|
-
|