gibbler 0.7.0 → 0.7.1

Sign up to get free protection for your applications and to get access to all the features.
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
-