gibbler 0.7.7 → 0.8.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (5) hide show
  1. data/CHANGES.txt +7 -0
  2. data/README.rdoc +40 -40
  3. data/gibbler.gemspec +1 -1
  4. data/lib/gibbler.rb +68 -52
  5. metadata +2 -2
data/CHANGES.txt CHANGED
@@ -1,5 +1,12 @@
1
1
  GIBBLER, CHANGES
2
2
 
3
+ #### 0.8.0 (2010-04-??) ###############################
4
+
5
+ * CHANGE: Gibber::Object#__gibbler now accepts only 1 optional argument: digest_type
6
+ * ADDED: Gibbler::Digest#to_i which assumes base 16
7
+ * ADDED: Gibbler::Object#gibbler now accepts a digest type
8
+ * ADDED: Gibbler::Digest#to_s and #base can take a base argument
9
+
3
10
  #### 0.7.7 (2010-03-29) ###############################
4
11
 
5
12
  * ADDED: Gibbler::Digest#shorten
data/README.rdoc CHANGED
@@ -1,12 +1,14 @@
1
- = Gibbler - v0.7 ALPHA
1
+ = Gibbler - v0.8
2
2
 
3
3
  Git-like hashes and history for Ruby objects for Ruby 1.8, 1.9 and JRuby.
4
4
 
5
5
  Check out the screencast[http://www.rubypulse.com/episode-0.3-gibbler.html] created by Alex Peuchert.
6
6
 
7
- === Important Information Regarding Your Digests
7
+ == Some things to keep in mind
8
8
 
9
- <i>Digest calculation changed in the 0.7 release for Proc objects. See "News" below for more info.</i>
9
+ * Digest calculation may change between minor releases (as it did between 0.6 and 0.7)
10
+ * Gibbler history is not suitable for very large objects since it keeps complete copies of the object in memory. This is a very early implementation of this feature so don't rely on it for production code.
11
+ * Don't forget to enjoy what you do!
10
12
 
11
13
 
12
14
  == Example 1 -- Basic Usage
@@ -88,7 +90,7 @@ If you have control over the namespaces of your objects, you can use the method
88
90
  a.changed? # => true
89
91
 
90
92
 
91
- The history methods also have aliases which remove the "gibbler_".
93
+ The history methods also have aliases which remove the "gibbler_" prefix.
92
94
 
93
95
  require 'gibbler/aliases'
94
96
  require 'gibbler/history'
@@ -99,6 +101,40 @@ The history methods also have aliases which remove the "gibbler_".
99
101
  a.revert!
100
102
  # etc...
101
103
 
104
+ == Example 4 -- Different Digest types
105
+
106
+ By default Gibbler creates SHA1 hashes. You can change this globally or per instance.
107
+
108
+ require 'gibbler'
109
+
110
+ Gibbler.digest_type = Digest::MD5
111
+
112
+ :kimmy.gibbler # => 0c61ff17f46223f355759934154d5dcb
113
+
114
+ :kimmy.gibbler(Digest::SHA1) # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
115
+
116
+
117
+ In Jruby, you can grab the digest types from the openssl library.
118
+
119
+ require 'openssl'
120
+
121
+ Gibbler.digest_type = OpenSSL::Digest::SHA256
122
+
123
+ :kimmy.gibbler # => 1069428e6273cf329436c3dce9b680d4d4e229d7b7...
124
+
125
+
126
+ == Example 5 -- All your base
127
+
128
+ require 'gibbler'
129
+
130
+ :kimmy.gibbler # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
131
+ :kimmy.gibbler.base(16) # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
132
+ :kimmy.gibbler.base(36) # => 9nydr6mpv6w4k8ngo3jtx0jz1n97h7j
133
+
134
+ :kimmy.gibbler.base(10) # => 472384540402900668368761869477227308873774630879
135
+ :kimmy.gibbler.to_i # => 472384540402900668368761869477227308873774630879
136
+
137
+
102
138
  == Supported Classes
103
139
 
104
140
  Gibbler methods are available only to the classes which explicitly include them (see RDocs[http://delano.github.com/gibbler] for details on which classes are supported by default). You can also extend custom objects:
@@ -127,42 +163,6 @@ Gibbler::String creates a digest based on the name of the class and the output o
127
163
  As of 0.7 all Proc objects have the same digest: <tt>12075835e94be34438376cd7a54c8db7e746f15d</tt>.
128
164
 
129
165
 
130
- == ALPHA Notice
131
-
132
- This code is fresh so the interface may change. Some things to keep in mind:
133
-
134
- * Gibbler history is not suitable for very large objects since it keeps complete copies of the object in memory. This is a very early implementation of this feature so don't rely on it for production code.
135
- * Digest calculation may change between minor releases (e.g. 0.6 to 0.7, etc)
136
- * Don't forget to enjoy what you do!
137
-
138
-
139
- == News
140
-
141
- === 2009-10-07: Digest calculation for Proc objects has changed.
142
-
143
- Proc digests are now based on the name of the class and the value of Proc#name (if available). Procs or objects containing Procs will have different digests than those created in previous releases.
144
-
145
- After much deliberation, I realized that Gibbler cares about the data and not the code. Procs are code, but a reference to a Proc in an instance variable is data. With this change all Proc objects have the same digest. This decision has the side benefit of increasing compatibility between Ruby 1.8, 1.9 & JRuby.
146
-
147
- This is the only change between 0.6.4 and 0.7.0 so if you prefer the previous calculation for Procs you can find it in that version.
148
-
149
- Happy Digesting!
150
-
151
- === 2009-10-07: Support for freezing and Regexp
152
-
153
- In 0.6.4, all Gibbler objects will create a new digest when <tt>obj.freeze</tt> is called. All subsequent calls to <tt>obj.gibbler</tt> will return the most recent digest without having to run the calculation again.
154
-
155
- I've also added support for Regexp out of the box.
156
-
157
- === 2009-07-20: Digest change for instances of Class, Module, and Proc
158
-
159
- Digest calculation has changed for Class, Module, and Proc objects. Digests created with Gibbler 0.5.x and earlier will not match the ones created by 0.6.
160
-
161
- * Class and Module objects were calculating digests based on the output of <tt>self.to_s</tt>. This was a problem because that string contains a memory address which can change arbitrarily. The new calculation is based on the object class, the length of name, and the name itself. e.g. <tt>"Class:6:Object" # => '5620e4a8b10ec6830fece61d33f5d3e9a349b4c2'</tt>
162
- * Proc objects were including the return value of <tt>self.binding</tt> in the digest calculation. This is not reliable because the binding includes an arbitrary address. The new calculation is based on the class name, the arity, and whether it was created with a lambda.
163
-
164
- Also note that this change affects the digests for Hashes and Arrays that contain instances of Class, Module, or Proc.
165
-
166
166
 
167
167
  == Known Issues
168
168
 
data/gibbler.gemspec CHANGED
@@ -1,7 +1,7 @@
1
1
  @spec = Gem::Specification.new do |s|
2
2
  s.name = "gibbler"
3
3
  s.rubyforge_project = "gibbler"
4
- s.version = "0.7.7"
4
+ s.version = "0.8.0"
5
5
  s.summary = "Gibbler: Git-like hashes for Ruby objects"
6
6
  s.description = s.summary
7
7
  s.author = "Delano Mandelbaum"
data/lib/gibbler.rb CHANGED
@@ -15,7 +15,7 @@ require 'digest/sha1'
15
15
  # "Hola, Tanneritos"
16
16
  #
17
17
  module Gibbler
18
- VERSION = "0.7.7"
18
+ VERSION = "0.8.0"
19
19
 
20
20
  require 'gibbler/mixins'
21
21
 
@@ -33,8 +33,23 @@ end
33
33
  #
34
34
  class Gibbler::Digest < String
35
35
 
36
+ # Return an integer assuming base 16.
37
+ def to_i(base=nil)
38
+ base ||= 16
39
+ super(base)
40
+ end
41
+
42
+ # Returns a string. Takes an optional base.
43
+ def to_s(base=nil)
44
+ base.nil? ? super() : super().to_i(16).to_s(base)
45
+ end
46
+
47
+ def base(base=16)
48
+ self.class.new(self.to_i(16).to_s(base))
49
+ end
50
+
36
51
  def base36
37
- self.class.new self.to_i(16).to_s(36)
52
+ base(36)
38
53
  end
39
54
 
40
55
  # Shorten the digest to the given (optional) length.
@@ -127,11 +142,11 @@ module Gibbler
127
142
  # If the object is frozen, this will return the value of
128
143
  # <tt>gibbler_cache</tt>.
129
144
  #
130
- def gibbler
145
+ def gibbler(digest_type=nil)
131
146
  #gibbler_debug caller[0]
132
147
  gibbler_debug :GIBBLER, self.class, self
133
148
  return self.gibbler_cache if self.frozen?
134
- self.gibbler_cache = Gibbler::Digest.new self.__gibbler
149
+ self.gibbler_cache = Gibbler::Digest.new self.__gibbler(digest_type)
135
150
  end
136
151
 
137
152
  # Has this object been modified?
@@ -162,11 +177,11 @@ module Gibbler
162
177
  # <b>This is a default method appropriate for only the most
163
178
  # basic objects like Class and Module.</b>
164
179
  #
165
- def __gibbler(h=self)
166
- klass = h.class
167
- nom = h.name if h.respond_to?(:name)
180
+ def __gibbler(digest_type=nil)
181
+ klass = self.class
182
+ nom = self.name if self.respond_to?(:name)
168
183
  nom ||= ''
169
- a = Gibbler.digest '%s:%s:%s' % [klass, nom.size, nom]
184
+ a = Gibbler.digest '%s:%s:%s' % [klass, nom.size, nom], digest_type
170
185
  gibbler_debug klass, a, [klass, nom.size, nom]
171
186
  a
172
187
  end
@@ -210,8 +225,9 @@ module Gibbler
210
225
  # Sends +str+ to Digest::SHA1.hexdigest. If another digest class
211
226
  # has been specified, that class will be used instead.
212
227
  # See: digest_type
213
- def self.digest(str)
214
- @@gibbler_digest_type.hexdigest str
228
+ def self.digest(str, digest_type=nil)
229
+ digest_type ||= @@gibbler_digest_type
230
+ digest_type.hexdigest str
215
231
  end
216
232
 
217
233
  def self.gibbler_debug(*args)
@@ -282,16 +298,16 @@ module Gibbler
282
298
  end
283
299
 
284
300
  # Creates a digest for the current state of self.
285
- def __gibbler(h=self)
286
- klass = h.class
301
+ def __gibbler(digest_type=nil)
302
+ klass = self.class
287
303
  d = []
288
304
  gibbler_debug :gibbler_fields, gibbler_fields
289
305
  gibbler_fields.each do |n|
290
306
  value = instance_variable_get("@#{n}")
291
- d << '%s:%s:%s' % [value.class, n, value.__gibbler]
307
+ d << '%s:%s:%s' % [value.class, n, value.__gibbler(digest_type)]
292
308
  end
293
- d = d.join(':').__gibbler
294
- a = Gibbler.digest "%s:%d:%s" % [klass, d.size, d]
309
+ d = d.join(':').__gibbler(digest_type)
310
+ a = Gibbler.digest "%s:%d:%s" % [klass, d.size, d], digest_type
295
311
  gibbler_debug klass, a, [klass, d.size, d]
296
312
  a
297
313
  end
@@ -330,10 +346,10 @@ module Gibbler
330
346
  end
331
347
 
332
348
  # Creates a digest for the current state of self.
333
- def __gibbler(h=self)
334
- klass = h.class
335
- value = h.nil? ? "\0" : h.to_s
336
- a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value]
349
+ def __gibbler(digest_type=nil)
350
+ klass = self.class
351
+ value = self.nil? ? "\0" : self.to_s
352
+ a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value], digest_type
337
353
  gibbler_debug klass, a, [klass, value.size, value]
338
354
  a
339
355
  end
@@ -365,15 +381,15 @@ module Gibbler
365
381
  end
366
382
 
367
383
  # Creates a digest for the current state of self.
368
- def __gibbler(h=self)
369
- klass = h.class
370
- d = h.keys.sort { |a,b| a.inspect <=> b.inspect }
384
+ def __gibbler(digest_type=nil)
385
+ klass = self.class
386
+ d = self.keys.sort { |a,b| a.inspect <=> b.inspect }
371
387
  d.collect! do |name|
372
- value = h[name]
373
- '%s:%s:%s' % [value.class, name, value.__gibbler]
388
+ value = self[name]
389
+ '%s:%s:%s' % [value.class, name, value.__gibbler(digest_type)]
374
390
  end
375
- d = d.join(':').__gibbler
376
- a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d]
391
+ d = d.join(':').__gibbler(digest_type)
392
+ a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d], digest_type
377
393
  gibbler_debug klass, a, [klass, d.size, d]
378
394
  a
379
395
  end
@@ -405,15 +421,15 @@ module Gibbler
405
421
  end
406
422
 
407
423
  # Creates a digest for the current state of self.
408
- def __gibbler(h=self)
409
- klass = h.class
424
+ def __gibbler(digest_type=nil)
425
+ klass = self.class
410
426
  d, index = [], 0
411
- h.each do |value|
412
- d << '%s:%s:%s' % [value.class, index, value.__gibbler]
427
+ self.each do |value|
428
+ d << '%s:%s:%s' % [value.class, index, value.__gibbler(digest_type)]
413
429
  index += 1
414
430
  end
415
- d = d.join(':').__gibbler
416
- a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d]
431
+ d = d.join(':').__gibbler(digest_type)
432
+ a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d], digest_type
417
433
  gibbler_debug klass, a, [klass, d.size, d]
418
434
  a
419
435
  end
@@ -441,10 +457,10 @@ module Gibbler
441
457
  end
442
458
 
443
459
  # Creates a digest for the current state of self.
444
- def __gibbler(h=self)
445
- klass = h.class
446
- value = h.nil? ? "\0" : h.utc.strftime('%Y-%m-%d %H:%M:%S UTC')
447
- a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value]
460
+ def __gibbler(digest_type=nil)
461
+ klass = self.class
462
+ value = self.nil? ? "\0" : self.utc.strftime('%Y-%m-%d %H:%M:%S UTC')
463
+ a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value], digest_type
448
464
  gibbler_debug klass, a, [klass, value.size, value]
449
465
  a
450
466
  end
@@ -472,10 +488,10 @@ module Gibbler
472
488
  end
473
489
 
474
490
  # Creates a digest for the current state of self.
475
- def __gibbler(h=self)
476
- klass = h.class
477
- value = h.nil? ? "\0" : h.new_offset(0).to_s
478
- a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value]
491
+ def __gibbler(digest_type=nil)
492
+ klass = self.class
493
+ value = self.nil? ? "\0" : self.new_offset(0).to_s
494
+ a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value], digest_type
479
495
  gibbler_debug klass, a, [klass, value.size, value]
480
496
  a
481
497
  end
@@ -505,11 +521,11 @@ module Gibbler
505
521
  end
506
522
 
507
523
  # Creates a digest for the current state of self.
508
- def __gibbler(h=self)
509
- klass = h.class
510
- value = h.nil? ? "\0" : h.to_s
511
- size = h.nil? ? 0 : h.to_a.size
512
- a = Gibbler.digest "%s:%d:%s" % [klass, size, value]
524
+ def __gibbler(digest_type=nil)
525
+ klass = self.class
526
+ value = self.nil? ? "\0" : self.to_s
527
+ size = self.nil? ? 0 : self.to_a.size
528
+ a = Gibbler.digest "%s:%d:%s" % [klass, size, value], digest_type
513
529
  gibbler_debug klass, a, [klass, size, value]
514
530
  a
515
531
  end
@@ -531,9 +547,9 @@ module Gibbler
531
547
  end
532
548
 
533
549
  # Creates a digest for the current state of self.
534
- def __gibbler(h=self)
535
- klass = h.class
536
- a = Gibbler.digest "%s:%s" % [klass, "\0"]
550
+ def __gibbler(digest_type=nil)
551
+ klass = self.class
552
+ a = Gibbler.digest "%s:%s" % [klass, "\0"], digest_type
537
553
  gibbler_debug klass, a, [klass, "\0"]
538
554
  a
539
555
  end
@@ -566,10 +582,10 @@ module Gibbler
566
582
  end
567
583
 
568
584
  # Creates a digest for the current state of self.
569
- def __gibbler(h=self)
570
- klass = h.class
571
- value = h.nil? ? "\0" : h.path
572
- a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value]
585
+ def __gibbler(digest_type=nil)
586
+ klass = self.class
587
+ value = self.nil? ? "\0" : self.path
588
+ a = Gibbler.digest "%s:%d:%s" % [klass, value.size, value], digest_type
573
589
  gibbler_debug klass, a, [klass, value.size, value]
574
590
  a
575
591
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: gibbler
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.7.7
4
+ version: 0.8.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Delano Mandelbaum
@@ -9,7 +9,7 @@ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
11
 
12
- date: 2010-03-29 00:00:00 -04:00
12
+ date: 2010-04-08 00:00:00 -04:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency