gibbler 0.9.0 → 0.10.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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
|
-
|