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