gibbler 0.7.0 → 0.7.1

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.
data/CHANGES.txt CHANGED
@@ -1,6 +1,11 @@
1
1
  GIBBLER, CHANGES
2
2
 
3
3
 
4
+ #### 0.7.1 (2009-10-09) #################################
5
+
6
+ * FIXED: Gibbler::Complex now sorts instance variables before processing.
7
+ This resolves the issue of digest compatibility between 1.8, 1.9, and JRuby.
8
+
4
9
  #### 0.7.0 (2009-10-07) #################################
5
10
 
6
11
  NOTE: Digest calculation for Proc objects has changed. Procs
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.0"
4
+ s.version = "0.7.1"
5
5
  s.summary = "Gibbler: Git-like hashes for Ruby objects"
6
6
  s.description = s.summary
7
7
  s.author = "Delano Mandelbaum"
@@ -35,29 +35,8 @@
35
35
  gibbler.gemspec
36
36
  lib/gibbler.rb
37
37
  lib/gibbler/aliases.rb
38
- lib/gibbler/digest.rb
39
38
  lib/gibbler/history.rb
40
39
  lib/gibbler/mixins.rb
41
- lib/gibbler/mixins/string.rb
42
- lib/gibbler/object.rb
43
- tryouts/01_mixins_tryouts.rb
44
- tryouts/02_compat_tryouts.rb
45
- tryouts/05_gibbler_digest_tryouts.rb
46
- tryouts/10_basic_tryouts.rb
47
- tryouts/11_basic_sha256_tryouts.rb
48
- tryouts/14_extended_tryouts.rb
49
- tryouts/15_file_tryouts.rb
50
- tryouts/16_uri_tryouts.rb
51
- tryouts/20_time_tryouts.rb
52
- tryouts/50_history_tryouts.rb
53
- tryouts/51_hash_history_tryouts.rb
54
- tryouts/52_array_history_tryouts.rb
55
- tryouts/53_string_history_tryouts.rb
56
- tryouts/57_arbitrary_history_tryouts.rb
57
- tryouts/59_history_exceptions_tryouts.rb
58
- tryouts/80_performance_tryouts.rb
59
- tryouts/90_alias_tryouts.rb
60
- tryouts/object_hash_demo.rb
61
40
  )
62
41
 
63
42
  s.has_rdoc = true
@@ -1,4 +1,9 @@
1
1
 
2
2
 
3
- require 'gibbler/mixins/string'
4
-
3
+ class String
4
+ unless method_defined? :clear
5
+ def clear
6
+ replace ""
7
+ end
8
+ end
9
+ end
data/lib/gibbler.rb CHANGED
@@ -8,17 +8,166 @@ require 'digest/sha1'
8
8
  # "Hola, Tanneritos"
9
9
  #
10
10
  module Gibbler
11
+ VERSION = "0.7.1"
11
12
 
12
- VERSION = "0.7.0"
13
-
14
- require 'gibbler/digest'
15
- require 'gibbler/object'
16
13
  require 'gibbler/mixins'
17
14
 
18
15
  class Error < RuntimeError
19
16
  def initialize(obj); @obj = obj; end
20
17
  end
21
18
 
19
+ end
20
+
21
+
22
+ # = Gibbler::Digest
23
+ #
24
+ # A tiny subclass of String which adds a
25
+ # few digest related convenience methods.
26
+ #
27
+ class Gibbler::Digest < String
28
+
29
+ # Returns the first 8 characters of itself (the digest).
30
+ #
31
+ # e.g.
32
+ #
33
+ # "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
34
+ # "kimmy".gibbler.short # => c8027100
35
+ #
36
+ def short
37
+ self[0..7]
38
+ end
39
+
40
+ # Returns the first 6 characters of itself (the digest).
41
+ #
42
+ # e.g.
43
+ #
44
+ # "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
45
+ # "kimmy".gibbler.tiny # => c80271
46
+ #
47
+ def shorter
48
+ self[0..5]
49
+ end
50
+
51
+ # Returns the first 4 characters of itself (the digest).
52
+ #
53
+ # e.g.
54
+ #
55
+ # "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
56
+ # "kimmy".gibbler.tiny # => c802
57
+ #
58
+ def tiny
59
+ self[0..3]
60
+ end
61
+
62
+ # Returns true when +ali+ matches +self+
63
+ #
64
+ # "kimmy".gibbler == "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
65
+ # "kimmy".gibbler == "c8027100" # => false
66
+ #
67
+ def ==(ali)
68
+ return true if self.to_s == ali.to_s
69
+ false
70
+ end
71
+
72
+ # Returns true when +g+ matches one of: +self+, +short+, +shorter+, +tiny+
73
+ #
74
+ # "kimmy".gibbler === "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
75
+ # "kimmy".gibbler === "c8027100" # => true
76
+ # "kimmy".gibbler === "c80271" # => true
77
+ # "kimmy".gibbler === "c802" # => true
78
+ #
79
+ def ===(g)
80
+ return true if [to_s, short, shorter, tiny].member?(g.to_s)
81
+ false
82
+ end
83
+ end
84
+
85
+ module Gibbler
86
+ module Object
87
+
88
+ def self.included(obj)
89
+ obj.extend Attic
90
+ obj.attic :gibbler_cache
91
+ # Backwards compatibility for <= 0.6.2
92
+ obj.send :alias_method, :__gibbler_cache, :gibbler_cache
93
+ end
94
+
95
+ # Calculates a digest for the current object instance.
96
+ # Objects that are a kind of Hash or Array are processed
97
+ # recursively. The length of the returned String depends
98
+ # on the digest type. Also stores the value in the attic.
99
+ #
100
+ # obj.gibbler # => a5b1191a
101
+ # obj.gibbler_cache # => a5b1191a
102
+ #
103
+ # Calling gibbler_cache returns the most recent digest
104
+ # without calculation.
105
+ #
106
+ # If the object is frozen, this will return the value of
107
+ # <tt>gibbler_cache</tt>.
108
+ #
109
+ def gibbler
110
+ #gibbler_debug caller[0]
111
+ gibbler_debug :GIBBLER, self.class, self
112
+ return self.gibbler_cache if self.frozen?
113
+ self.gibbler_cache = Gibbler::Digest.new self.__gibbler
114
+ end
115
+
116
+ # Has this object been modified?
117
+ #
118
+ # This method compares the return value from digest with the
119
+ # previous value returned by gibbler (the value is stored in
120
+ # the attic as <tt>gibbler_cache</tt>).
121
+ # See Attic[http://github.com/delano/attic]
122
+ def gibbled?
123
+ self.gibbler_cache ||= self.gibbler
124
+ was, now = self.gibbler_cache.clone, self.gibbler
125
+ gibbler_debug :gibbled?, was, now
126
+ was != now
127
+ end
128
+
129
+ def gibbler_debug(*args)
130
+ return unless Gibbler.debug?
131
+ p args
132
+ end
133
+
134
+ # Creates a digest for the current state of self based on:
135
+ # * Object#class
136
+ # * Length of Object#name || 0
137
+ # * Object#name || ''
138
+ #
139
+ # e.g. Digest::SHA1.hexdigest "Class:6:Object" #=>
140
+ #
141
+ # <b>This is a default method appropriate for only the most
142
+ # basic objects like Class and Module.</b>
143
+ #
144
+ def __gibbler(h=self)
145
+ klass = h.class
146
+ nom = h.name if h.respond_to?(:name)
147
+ nom ||= ''
148
+ a = Gibbler.digest '%s:%s:%s' % [klass, nom.size, nom]
149
+ gibbler_debug klass, a, [klass, nom.size, nom]
150
+ a
151
+ end
152
+
153
+ # A simple override on Object#freeze to create a digest
154
+ # before the object is frozen. Once the object is frozen
155
+ # <tt>obj.gibbler</tt> will return the cached value with
156
+ # out calculation.
157
+ def freeze()
158
+ #gibbler_debug :freeze, caller[0]
159
+ self.gibbler
160
+ super
161
+ self
162
+ end
163
+
164
+ end
165
+
166
+ end
167
+
168
+
169
+ module Gibbler
170
+
22
171
  @@gibbler_debug = false
23
172
  @@gibbler_digest_type = ::Digest::SHA1
24
173
 
@@ -88,7 +237,8 @@ module Gibbler
88
237
  def __gibbler(h=self)
89
238
  klass = h.class
90
239
  d = []
91
- instance_variables.each do |n|
240
+ gibbler_debug :ivars, instance_variables.sort
241
+ instance_variables.sort.each do |n|
92
242
  value = instance_variable_get(n)
93
243
  d << '%s:%s:%s' % [value.class, n, value.__gibbler]
94
244
  end
@@ -209,12 +359,17 @@ module Gibbler
209
359
  # Creates a digest for the current state of self.
210
360
  def __gibbler(h=self)
211
361
  klass = h.class
212
- d, index = [], 0
213
- h.each do |value|
214
- d << '%s:%s:%s' % [value.class, index, value.__gibbler]
215
- index += 1
362
+ d, idx = [], 0
363
+ shorts = ['String', 'Fixnum', 'Symbol']
364
+ h.each do |v| # Some Array-like classes don't have each_with_index
365
+ if shorts.member?(v.class.to_s)
366
+ d << '%s:%s:%s:%s' % [v.class, idx, v.to_s.size, v.to_s]
367
+ else
368
+ d << '%s:%s:%s' % [v.class, idx, v.__gibbler]
369
+ end
370
+ idx += 1
216
371
  end
217
- d = d.join(':').__gibbler
372
+ d = d.join(':')
218
373
  a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d]
219
374
  gibbler_debug klass, a, [klass, d.size, d]
220
375
  a
@@ -401,6 +556,7 @@ module Gibbler
401
556
 
402
557
  end
403
558
 
559
+
404
560
  class NilClass; include Gibbler::Nil; end
405
561
  class Class; include Gibbler::Object; end
406
562
  class Module; include Gibbler::Object; 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.0
4
+ version: 0.7.1
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: 2009-10-07 00:00:00 -04:00
12
+ date: 2009-11-23 00:00:00 -05:00
13
13
  default_executable:
14
14
  dependencies:
15
15
  - !ruby/object:Gem::Dependency
@@ -39,29 +39,8 @@ files:
39
39
  - gibbler.gemspec
40
40
  - lib/gibbler.rb
41
41
  - lib/gibbler/aliases.rb
42
- - lib/gibbler/digest.rb
43
42
  - lib/gibbler/history.rb
44
43
  - lib/gibbler/mixins.rb
45
- - lib/gibbler/mixins/string.rb
46
- - lib/gibbler/object.rb
47
- - tryouts/01_mixins_tryouts.rb
48
- - tryouts/02_compat_tryouts.rb
49
- - tryouts/05_gibbler_digest_tryouts.rb
50
- - tryouts/10_basic_tryouts.rb
51
- - tryouts/11_basic_sha256_tryouts.rb
52
- - tryouts/14_extended_tryouts.rb
53
- - tryouts/15_file_tryouts.rb
54
- - tryouts/16_uri_tryouts.rb
55
- - tryouts/20_time_tryouts.rb
56
- - tryouts/50_history_tryouts.rb
57
- - tryouts/51_hash_history_tryouts.rb
58
- - tryouts/52_array_history_tryouts.rb
59
- - tryouts/53_string_history_tryouts.rb
60
- - tryouts/57_arbitrary_history_tryouts.rb
61
- - tryouts/59_history_exceptions_tryouts.rb
62
- - tryouts/80_performance_tryouts.rb
63
- - tryouts/90_alias_tryouts.rb
64
- - tryouts/object_hash_demo.rb
65
44
  has_rdoc: true
66
45
  homepage: http://github.com/delano/gibbler
67
46
  licenses: []
@@ -90,7 +69,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
90
69
  requirements: []
91
70
 
92
71
  rubyforge_project: gibbler
93
- rubygems_version: 1.3.2
72
+ rubygems_version: 1.3.5
94
73
  signing_key:
95
74
  specification_version: 3
96
75
  summary: "Gibbler: Git-like hashes for Ruby objects"
@@ -1,63 +0,0 @@
1
-
2
- # = Gibbler::Digest
3
- #
4
- # A tiny subclass of String which adds a
5
- # few digest related convenience methods.
6
- #
7
- class Gibbler::Digest < String
8
-
9
- # Returns the first 8 characters of itself (the digest).
10
- #
11
- # e.g.
12
- #
13
- # "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
14
- # "kimmy".gibbler.short # => c8027100
15
- #
16
- def short
17
- self[0..7]
18
- end
19
-
20
- # Returns the first 6 characters of itself (the digest).
21
- #
22
- # e.g.
23
- #
24
- # "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
25
- # "kimmy".gibbler.tiny # => c80271
26
- #
27
- def shorter
28
- self[0..5]
29
- end
30
-
31
- # Returns the first 4 characters of itself (the digest).
32
- #
33
- # e.g.
34
- #
35
- # "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
36
- # "kimmy".gibbler.tiny # => c802
37
- #
38
- def tiny
39
- self[0..3]
40
- end
41
-
42
- # Returns true when +ali+ matches +self+
43
- #
44
- # "kimmy".gibbler == "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
45
- # "kimmy".gibbler == "c8027100" # => false
46
- #
47
- def ==(ali)
48
- return true if self.to_s == ali.to_s
49
- false
50
- end
51
-
52
- # Returns true when +g+ matches one of: +self+, +short+, +shorter+, +tiny+
53
- #
54
- # "kimmy".gibbler === "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
55
- # "kimmy".gibbler === "c8027100" # => true
56
- # "kimmy".gibbler === "c80271" # => true
57
- # "kimmy".gibbler === "c802" # => true
58
- #
59
- def ===(g)
60
- return true if [to_s, short, shorter, tiny].member?(g.to_s)
61
- false
62
- end
63
- end
@@ -1,9 +0,0 @@
1
-
2
-
3
- class String
4
- unless method_defined? :clear
5
- def clear
6
- replace ""
7
- end
8
- end
9
- end
@@ -1,79 +0,0 @@
1
-
2
-
3
- module Gibbler
4
-
5
- module Object
6
-
7
- def self.included(obj)
8
- obj.extend Attic
9
- obj.attic :gibbler_cache
10
- # Backwards compatibility for <= 0.6.2
11
- obj.send :alias_method, :__gibbler_cache, :gibbler_cache
12
- end
13
-
14
- # Calculates a digest for the current object instance.
15
- # Objects that are a kind of Hash or Array are processed
16
- # recursively. The length of the returned String depends
17
- # on the digest type. Also stores the value in the attic.
18
- #
19
- # obj.gibbler # => a5b1191a
20
- # obj.gibbler_cache # => a5b1191a
21
- #
22
- # Calling gibbler_cache returns the most recent digest
23
- # without calculation.
24
- #
25
- # If the object is frozen, this will return the value of
26
- # <tt>gibbler_cache</tt>.
27
- #
28
- def gibbler
29
- gibbler_debug :GIBBLER, self.class, self
30
- return self.gibbler_cache if self.frozen?
31
- self.gibbler_cache = Gibbler::Digest.new self.__gibbler
32
- end
33
-
34
- # Has this object been modified?
35
- #
36
- # This method compares the return value from digest with the
37
- # previous value returned by gibbler (the value is stored in
38
- # the attic as <tt>gibbler_cache</tt>).
39
- # See Attic[http://github.com/delano/attic]
40
- def gibbled?
41
- self.gibbler_cache ||= self.gibbler
42
- was, now = self.gibbler_cache.clone, self.gibbler
43
- gibbler_debug :gibbled?, was, now
44
- was != now
45
- end
46
-
47
- def gibbler_debug(*args)
48
- return unless Gibbler.debug?
49
- p args
50
- end
51
-
52
- # Creates a digest for the current state of self based on:
53
- # * Object#class
54
- # * Length of Object#name || 0
55
- # * Object#name || ''
56
- #
57
- # e.g. Digest::SHA1.hexdigest "Class:6:Object" #=>
58
- #
59
- # <b>This is a default method appropriate for only the most
60
- # basic objects like Class and Module.</b>
61
- #
62
- def __gibbler(h=self)
63
- klass = h.class
64
- nom = h.name if h.respond_to?(:name)
65
- nom ||= ''
66
- a = Gibbler.digest '%s:%s:%s' % [klass, nom.size, nom]
67
- gibbler_debug klass, a, [klass, nom.size, nom]
68
- a
69
- end
70
-
71
- # A simple override on Object#freeze to create a digest
72
- # before the object is frozen. Once the object is frozen
73
- # <tt>obj.gibbler</tt> will return the cached value with
74
- # out calculation.
75
- def freeze() self.gibbler; super; self end
76
-
77
- end
78
-
79
- end
@@ -1,13 +0,0 @@
1
-
2
- library :gibbler, 'lib'
3
-
4
- group "Mixins"
5
-
6
- tryouts "String" do
7
-
8
- drill "has String#clear" do
9
- "".respond_to? :clear
10
- end
11
-
12
- end
13
-
@@ -1,25 +0,0 @@
1
-
2
- library :gibbler, 'lib'
3
-
4
- group "Gibbler::Digest"
5
-
6
- tryouts "Backwards compatability" do
7
-
8
- dream true
9
- drill "Gibbler Objects have gibbler_cache method" do
10
- "kimmy".respond_to? :gibbler_cache
11
- end
12
-
13
- dream true
14
- drill "Gibbler Objects have __gibbler_cache method" do
15
- "kimmy".respond_to? :__gibbler_cache
16
- end
17
-
18
- dream true
19
- drill "__gibbler_cache returns the same value as gibbler_cache" do
20
- a = "kimmy" and a.gibbler
21
- a.__gibbler_cache == a.gibbler_cache
22
- end
23
-
24
- end
25
-
@@ -1,31 +0,0 @@
1
-
2
- library :gibbler, 'lib'
3
-
4
- group "Gibbler::Digest"
5
-
6
- tryouts "All methods" do
7
-
8
-
9
- dream :class, Gibbler::Digest
10
- dream 'c8027100'
11
- drill "has short method" do
12
- "kimmy".gibbler.short
13
- end
14
-
15
- dream :class, Gibbler::Digest
16
- dream "12345678"
17
- drill "can Gibbler::Digest#short" do
18
- Gibbler::Digest.new("1234567890").short
19
- end
20
-
21
- drill "== is strict (only exact matches)", false do
22
- Gibbler::Digest.new("1234567890") == "12345678"
23
- end
24
-
25
- drill "=== is relaxed (allows partial matches)", true do
26
- Gibbler::Digest.new("1234567890") === "12345678"
27
- end
28
-
29
-
30
- end
31
-