gibbler 0.5.1 → 0.5.2
Sign up to get free protection for your applications and to get access to all the features.
- data/CHANGES.txt +7 -0
- data/README.rdoc +37 -5
- data/gibbler.gemspec +1 -1
- data/lib/gibbler.rb +35 -54
- metadata +2 -2
data/CHANGES.txt
CHANGED
@@ -1,6 +1,13 @@
|
|
1
1
|
GIBBLER, CHANGES
|
2
2
|
|
3
3
|
|
4
|
+
#### 0.5.2 (2009-07-??) #################################
|
5
|
+
|
6
|
+
* CHANGE: Moved Gibbler instance methods to Gibbler::Object
|
7
|
+
* ADDED: Proc.gibbler which is included by default
|
8
|
+
* ADDED: gibbler aliases to allow shorter methods by request.
|
9
|
+
|
10
|
+
|
4
11
|
#### 0.5.1 (2009-07-06) #################################
|
5
12
|
|
6
13
|
* CHANGE: Renamed gibbler_revert to gibbler_revert! (Thanks ivey)
|
data/README.rdoc
CHANGED
@@ -2,6 +2,9 @@
|
|
2
2
|
|
3
3
|
Git-like hashes and history for Ruby objects.
|
4
4
|
|
5
|
+
NOTE: Gibbler supports Ruby 1.8, 1.9 and JRuby.
|
6
|
+
|
7
|
+
|
5
8
|
== Example 1 -- Basic Usage
|
6
9
|
|
7
10
|
require 'gibbler'
|
@@ -61,6 +64,35 @@ Gibbler can also keep track of the history of changes to an object. By default G
|
|
61
64
|
|
62
65
|
http://delano.github.com/gibbler/img/whoababy.gif
|
63
66
|
|
67
|
+
|
68
|
+
== Example 3 -- Method Aliases
|
69
|
+
|
70
|
+
If you have control over the namespaces of your objects, you can use the method aliases to tighten up your code a bit. The "gibbler" and "gibbled?" methods can be accessed via "digest" and "changed?", respectively. (The reason they're not enabled by default is to avoid conflicts.)
|
71
|
+
|
72
|
+
require 'gibbler'
|
73
|
+
require 'gibbler/aliases'
|
74
|
+
|
75
|
+
"kimmy".digest # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
76
|
+
:kimmy.digest # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
|
77
|
+
|
78
|
+
a = [:a, :b, :c]
|
79
|
+
a.digest # => e554061823b8f06367555d1ee4c25b4ffee61944
|
80
|
+
a << :d
|
81
|
+
a.changed? # => true
|
82
|
+
|
83
|
+
|
84
|
+
The history methods also have aliases which remove the "gibbler_".
|
85
|
+
|
86
|
+
require 'gibbler'
|
87
|
+
require 'gibbler/history'
|
88
|
+
require 'gibbler/aliases'
|
89
|
+
|
90
|
+
|
91
|
+
a = { :magic => :original }
|
92
|
+
a.commit
|
93
|
+
a.history
|
94
|
+
a.revert!
|
95
|
+
# etc...
|
64
96
|
|
65
97
|
== Supported Classes
|
66
98
|
|
@@ -85,7 +117,7 @@ If you want to support all Ruby objects, add the following to your application:
|
|
85
117
|
include Gibbler::String
|
86
118
|
end
|
87
119
|
|
88
|
-
Gibbler::String creates a digest based on the name of the class and the output of the to_s method. This is a reasonable default for most objects however any object that includes the object address in to_s (e.g. "
|
120
|
+
Gibbler::String creates a digest based on the name of the class and the output of the to_s method. This is a reasonable default for most objects however any object that includes the object address in to_s (e.g. "Object:0x0x4ac9f0...") will produce unreliable digests (because the address can change).
|
89
121
|
|
90
122
|
|
91
123
|
== ALPHA Notice
|
@@ -97,14 +129,14 @@ NOTE: Gibbler history is not suitable for very large objects since it keeps comp
|
|
97
129
|
|
98
130
|
== News
|
99
131
|
|
100
|
-
=== 2009-07-
|
132
|
+
=== 2009-07-07: Added aliases
|
101
133
|
|
102
|
-
The
|
134
|
+
The "gibbler" methods can be cumbersome so I added some aliases which can be included by request. See the example above.
|
103
135
|
|
104
136
|
|
105
|
-
=== 2009-07-
|
137
|
+
=== 2009-07-06: Renamed gibbler_revert to gibbler_revert!
|
106
138
|
|
107
|
-
|
139
|
+
The gibbler_revert! method modifies the object in place so this was an important change to follow the Ruby convention of appending the exclamation mark. Thanks to ivey[http://news.ycombinator.com/item?id=689750] for pointing this out.
|
108
140
|
|
109
141
|
|
110
142
|
== Known Issues
|
data/gibbler.gemspec
CHANGED
data/lib/gibbler.rb
CHANGED
@@ -6,8 +6,9 @@ require 'digest/sha1'
|
|
6
6
|
# "Hola, Tanneritos"
|
7
7
|
#
|
8
8
|
module Gibbler
|
9
|
-
VERSION = "0.5.
|
9
|
+
VERSION = "0.5.2"
|
10
10
|
|
11
|
+
require 'gibbler/object'
|
11
12
|
require 'gibbler/digest'
|
12
13
|
require 'gibbler/mixins'
|
13
14
|
|
@@ -32,22 +33,6 @@ module Gibbler
|
|
32
33
|
def self.disable_debug; @@gibbler_debug = false; end
|
33
34
|
# Returns the current digest class.
|
34
35
|
def self.digest_type; @@gibbler_digest_type; end
|
35
|
-
|
36
|
-
# Calculates a digest for the current object instance.
|
37
|
-
# Objects that are a kind of Hash or Array are processed
|
38
|
-
# recursively. The length of the returned String depends
|
39
|
-
# on the digest type.
|
40
|
-
def gibbler
|
41
|
-
#if h.respond_to? :__custom_gibbler
|
42
|
-
# d = h.__custom_gibbler
|
43
|
-
# a = __gibbler '%s:%s:%s' % [klass, d.size, d]
|
44
|
-
# gibbler_debug [klass, a]
|
45
|
-
# a
|
46
|
-
#end
|
47
|
-
gibbler_debug :GIBBLER, self.class, self
|
48
|
-
@__gibbler_digest__ = Gibbler::Digest.new self.__gibbler
|
49
|
-
@__gibbler_digest__
|
50
|
-
end
|
51
36
|
|
52
37
|
# Sends +str+ to Digest::SHA1.hexdigest. If another digest class
|
53
38
|
# has been specified, that class will be used instead.
|
@@ -56,46 +41,13 @@ module Gibbler
|
|
56
41
|
@@gibbler_digest_type.hexdigest str
|
57
42
|
end
|
58
43
|
|
59
|
-
# Has this object been modified?
|
60
|
-
#
|
61
|
-
# This method compares the return value from digest with the
|
62
|
-
# previous value returned by gibbler (the value is stored in
|
63
|
-
# <tt>@__gibbler_digest__</tt>)
|
64
|
-
def gibbled?
|
65
|
-
@__gibbler_digest__ ||= self.gibbler
|
66
|
-
was, now = @__gibbler_digest__.clone, self.gibbler
|
67
|
-
gibbler_debug :gibbled?, was, now
|
68
|
-
was != now
|
69
|
-
end
|
70
|
-
|
71
|
-
def gibbler_debug(*args)
|
72
|
-
return unless Gibbler.debug?
|
73
|
-
p args
|
74
|
-
end
|
75
44
|
def self.gibbler_debug(*args)
|
76
45
|
return unless Gibbler.debug?
|
77
46
|
p args
|
78
47
|
end
|
79
48
|
|
80
|
-
# Gets the list of instance variables from the standard implementation
|
81
|
-
# of the instance_variables method and removes all that
|
82
|
-
# begin with <tt>@__gibbler</tt>.
|
83
|
-
# Any class the includes Gibbler or Gibbler::* will use this version of
|
84
|
-
# instance_variables. It's important because we don't want the current
|
85
|
-
# digest value to affect the next gibble.
|
86
|
-
#
|
87
|
-
# This is also critical for objects that include Gibbler::Complex b/c
|
88
|
-
# it deals explicitly with instance variables. If it sees the __gibbler
|
89
|
-
# variables it will go bananas.
|
90
|
-
#
|
91
|
-
def instance_variables
|
92
|
-
vars = super
|
93
|
-
vars.reject! { |e| e.to_s =~ /^@__gibble/ }
|
94
|
-
vars
|
95
|
-
end
|
96
|
-
|
97
49
|
module Complex
|
98
|
-
include Gibbler
|
50
|
+
include Gibbler::Object
|
99
51
|
# Creates a digest based on:
|
100
52
|
# * An Array of instance variable names and values in the format: <tt>CLASS:LENGTH:VALUE</tt>
|
101
53
|
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
@@ -133,7 +85,7 @@ module Gibbler
|
|
133
85
|
end
|
134
86
|
|
135
87
|
module String
|
136
|
-
include Gibbler
|
88
|
+
include Gibbler::Object
|
137
89
|
# Creates a digest based on: <tt>CLASS:LENGTH:VALUE</tt>.
|
138
90
|
# This method can be used for any class where the <tt>to_s</tt>
|
139
91
|
# method returns an appropriate unique value for this instance.
|
@@ -159,7 +111,7 @@ module Gibbler
|
|
159
111
|
end
|
160
112
|
|
161
113
|
module Hash
|
162
|
-
include Gibbler
|
114
|
+
include Gibbler::Object
|
163
115
|
|
164
116
|
# Creates a digest based on:
|
165
117
|
# * parse each key, value pair into an Array containing keys: <tt>CLASS:KEY:VALUE.__gibbler</tt>
|
@@ -195,7 +147,7 @@ module Gibbler
|
|
195
147
|
end
|
196
148
|
|
197
149
|
module Array
|
198
|
-
include Gibbler
|
150
|
+
include Gibbler::Object
|
199
151
|
|
200
152
|
# Creates a digest based on:
|
201
153
|
# * parse each element into an Array of digests like: <tt>CLASS:INDEX:VALUE.__gibbler</tt>
|
@@ -230,6 +182,31 @@ module Gibbler
|
|
230
182
|
end
|
231
183
|
end
|
232
184
|
|
185
|
+
# Return the digest for <tt>class:arity:binding</tt>, where:
|
186
|
+
# * class is the current class name (e.g. Proc)
|
187
|
+
# * arity is the value returned by <tt>Proc#arity</tt>
|
188
|
+
# * binding is the value returned by <tt>Proc#binding</tt>
|
189
|
+
#
|
190
|
+
# This method can be used by any subclass of Proc.
|
191
|
+
#
|
192
|
+
# NOTE: This is named "Block" because for some reason if this is
|
193
|
+
# named "Proc" (as in Gibbler::Proc) and the Rye library is also
|
194
|
+
# required, a runtime error is raised (Ruby 1.9.1 only):
|
195
|
+
#
|
196
|
+
# undefined method `new' for Gibbler::Proc:Module
|
197
|
+
# /usr/local/lib/ruby/1.9.1/tempfile.rb:169:in `callback'
|
198
|
+
# /usr/local/lib/ruby/1.9.1/tempfile.rb:61:in `initialize'
|
199
|
+
# /Users/delano/Projects/opensource/rye/lib/rye.rb:210:in `new'
|
200
|
+
#
|
201
|
+
module Block
|
202
|
+
include Gibbler::Object
|
203
|
+
def __gibbler(h=self)
|
204
|
+
klass = h.class
|
205
|
+
a = Gibbler.digest '%s:%s:%s' % [klass, h.arity, h.binding]
|
206
|
+
gibbler_debug klass, a, [klass, h.arity, h.binding]
|
207
|
+
a
|
208
|
+
end
|
209
|
+
end
|
233
210
|
|
234
211
|
##--
|
235
212
|
## NOTE: this was used when Gibbler supported "include Gibbler". We
|
@@ -255,6 +232,10 @@ module Gibbler
|
|
255
232
|
|
256
233
|
end
|
257
234
|
|
235
|
+
class Proc
|
236
|
+
include Gibbler::Block
|
237
|
+
end
|
238
|
+
|
258
239
|
class Hash
|
259
240
|
include Gibbler::Hash
|
260
241
|
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.5.
|
4
|
+
version: 0.5.2
|
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-07-
|
12
|
+
date: 2009-07-07 00:00:00 -04:00
|
13
13
|
default_executable:
|
14
14
|
dependencies: []
|
15
15
|
|