gibbler 0.8.10 → 0.9.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.
- data/CHANGES.txt +12 -1
- data/LICENSE.txt +1 -1
- data/README.rdoc +25 -17
- data/Rakefile +7 -32
- data/VERSION.yml +2 -2
- data/gibbler.gemspec +36 -34
- data/lib/gibbler.rb +142 -126
- data/lib/gibbler/aliases.rb +2 -2
- data/lib/gibbler/history.rb +1 -1
- data/lib/gibbler/mixins.rb +32 -7
- data/try/{01_mixins_try.rb → 01_core_ext_try.rb} +1 -1
- data/try/02_compat_try.rb +1 -1
- data/try/05_gibbler_digest_try.rb +1 -1
- data/try/10_standalone_try.rb +49 -0
- data/try/{10_basic_try.rb → 11_basic_try.rb} +2 -2
- data/try/{11_basic_sha256_try.rb → 12_basic_sha256_try.rb} +1 -1
- data/try/14_extended_try.rb +1 -1
- data/try/15_file_try.rb +1 -1
- data/try/16_uri_try.rb +1 -1
- data/try/17_complex_object_try.rb +5 -2
- data/try/18_proc_try.rb +1 -1
- data/try/20_time_try.rb +1 -1
- data/try/30_secret_try.rb +1 -1
- data/try/50_history_try.rb +1 -1
- data/try/51_hash_history_try.rb +1 -1
- data/try/52_array_history_try.rb +1 -1
- data/try/53_string_history_try.rb +1 -1
- data/try/57_arbitrary_history_try.rb +1 -1
- data/try/59_history_exceptions_try.rb +1 -1
- metadata +25 -42
data/CHANGES.txt
CHANGED
@@ -1,5 +1,16 @@
|
|
1
1
|
GIBBLER, CHANGES
|
2
2
|
|
3
|
+
|
4
|
+
#### 0.9.0 (2012-04-20) ###############################
|
5
|
+
|
6
|
+
* FIXED: Gibbler::Complex now checks has_method? and will use that before instance variables.
|
7
|
+
* CHANGE: Gibbler is now a class which supplies the default standalone usage
|
8
|
+
* CHANGE: Ruby object mixins must now be explicitly loaded via "require 'gibbler/mixins'"
|
9
|
+
* CHANGE: Removed Gibbler.enable_debug/disable_debug
|
10
|
+
* CHANGE: Gibbler.digest now returns nil for an empty Array
|
11
|
+
* ADDED: Gibbler.delimiter
|
12
|
+
|
13
|
+
|
3
14
|
#### 0.8.10 (2011-10-23) ###############################
|
4
15
|
|
5
16
|
* CHANGE: Gibbler::Hash and Gibbler::Array now skip values that have no __gibbler method
|
@@ -199,7 +210,7 @@ NOTE: Calculated digests have changed since 0.3. Most digests created with
|
|
199
210
|
* CHANGE: Gibbler methods are no longer available to all Ruby classes
|
200
211
|
by default. The default list is now: String, Hash, Array, Symbol,
|
201
212
|
Class, Fixnum, Bignum.
|
202
|
-
* CHANGE: Renamed Gibbler.
|
213
|
+
* CHANGE: Renamed Gibbler.digest_type to Gibbler.digest_type
|
203
214
|
* ADDED: Custom objects can now "include Gibbler::Complex"
|
204
215
|
|
205
216
|
|
data/LICENSE.txt
CHANGED
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Gibbler - v0.
|
1
|
+
= Gibbler - v0.9
|
2
2
|
|
3
3
|
Git-like hashes and history for Ruby objects for Ruby 1.8, 1.9 and JRuby.
|
4
4
|
|
@@ -8,13 +8,23 @@ Check out the screencast[http://www.rubypulse.com/episode-0.3-gibbler.html] crea
|
|
8
8
|
|
9
9
|
* Digest calculation may change between minor releases (as it did between 0.6 and 0.7)
|
10
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
|
11
|
+
* Don't forget to enjoy your life!
|
12
12
|
|
13
13
|
|
14
|
-
== Example 1 --
|
14
|
+
== Example 1 -- Standalone Usage
|
15
15
|
|
16
16
|
require 'gibbler'
|
17
17
|
|
18
|
+
g = Gibbler.new 'id', 1001 # => f4fb3796ababa3788d1bded8fdc589ab1ccb1c3d
|
19
|
+
g.base(36) # => sm71s7eam4hm5jlsuzlqkbuktwpe5h9
|
20
|
+
|
21
|
+
g == 'f4fb3796ababa3788d1bded8fdc589ab1ccb1c3d' # => true
|
22
|
+
g === 'f4fb379' # => true
|
23
|
+
|
24
|
+
== Example 2 -- Mixins Usage
|
25
|
+
|
26
|
+
require 'gibbler/mixins'
|
27
|
+
|
18
28
|
"kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
19
29
|
:kimmy.gibbler # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
|
20
30
|
|
@@ -40,11 +50,11 @@ Check out the screencast[http://www.rubypulse.com/episode-0.3-gibbler.html] crea
|
|
40
50
|
config.gibbler.base36.short # => 8x00l83j
|
41
51
|
|
42
52
|
|
43
|
-
== Example
|
53
|
+
== Example 3 -- Object History
|
44
54
|
|
45
55
|
Gibbler can also keep track of the history of changes to an object. By default Gibbler supports history for Hash, Array, and String objects. The <tt>gibbler_commit</tt> method creates a clone of the current object and stores in an instance variable using the current hash digest as the key.
|
46
56
|
|
47
|
-
require 'gibbler'
|
57
|
+
require 'gibbler/mixins'
|
48
58
|
require 'gibbler/history'
|
49
59
|
|
50
60
|
a = { :magic => :original }
|
@@ -75,7 +85,7 @@ Gibbler can also keep track of the history of changes to an object. By default G
|
|
75
85
|
http://delano.github.com/gibbler/img/whoababy.gif
|
76
86
|
|
77
87
|
|
78
|
-
== Example
|
88
|
+
== Example 4 -- Method Aliases
|
79
89
|
|
80
90
|
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.)
|
81
91
|
|
@@ -101,11 +111,11 @@ The history methods also have aliases which remove the "gibbler_" prefix.
|
|
101
111
|
a.revert!
|
102
112
|
# etc...
|
103
113
|
|
104
|
-
== Example
|
114
|
+
== Example 5 -- Different Digest types
|
105
115
|
|
106
116
|
By default Gibbler creates SHA1 hashes. You can change this globally or per instance.
|
107
117
|
|
108
|
-
require 'gibbler'
|
118
|
+
require 'gibbler/mixins'
|
109
119
|
|
110
120
|
Gibbler.digest_type = Digest::MD5
|
111
121
|
|
@@ -123,9 +133,9 @@ In Jruby, you can grab the digest types from the openssl library.
|
|
123
133
|
:kimmy.gibbler # => 1069428e6273cf329436c3dce9b680d4d4e229d7b7...
|
124
134
|
|
125
135
|
|
126
|
-
== Example
|
136
|
+
== Example 6 -- All your base
|
127
137
|
|
128
|
-
require 'gibbler'
|
138
|
+
require 'gibbler/mixins'
|
129
139
|
|
130
140
|
:kimmy.gibbler # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
|
131
141
|
:kimmy.gibbler.base(16) # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
|
@@ -135,11 +145,11 @@ In Jruby, you can grab the digest types from the openssl library.
|
|
135
145
|
:kimmy.gibbler.to_i # => 472384540402900668368761869477227308873774630879
|
136
146
|
|
137
147
|
|
138
|
-
== Example
|
148
|
+
== Example 7 -- Global secret
|
139
149
|
|
140
150
|
Gibbler can prepend all digest inputs with a global secret. You can set this once per project to ensure your project's digests are unique.
|
141
151
|
|
142
|
-
require 'gibbler'
|
152
|
+
require 'gibbler/mixins'
|
143
153
|
|
144
154
|
:kimmy.gibbler # => 52be7494a602d85ff5d8a8ab4ffe7f1b171587df
|
145
155
|
|
@@ -180,17 +190,15 @@ As of 0.7 all Proc objects have the same digest: <tt>12075835e94be34438376cd7a54
|
|
180
190
|
== Known Issues
|
181
191
|
|
182
192
|
* gibbler or gibbled? must be called at least once before gibbled? will be able to return a useful value (otherwise there is no previous digest value to compare to)
|
183
|
-
* Digests for Bignum objects are different between Ruby and JRuby.
|
193
|
+
* Digests for Bignum objects are different between Ruby and JRuby. Why?
|
184
194
|
* Digests for Proc objects are different between Ruby 1.8 and 1.9 because Proc.arity returns different values and 1.8 has no lambda? method.
|
185
195
|
|
186
196
|
|
187
197
|
== Installation
|
188
198
|
|
189
|
-
Via Rubygems
|
199
|
+
Via Rubygems:
|
190
200
|
|
191
201
|
$ gem install gibbler
|
192
|
-
$ gem install delano-gibbler
|
193
|
-
|
194
202
|
|
195
203
|
or via download:
|
196
204
|
* gibbler-latest.tar.gz[http://github.com/delano/gibbler/tarball/latest]
|
@@ -220,7 +228,7 @@ or via download:
|
|
220
228
|
|
221
229
|
== Credits
|
222
230
|
|
223
|
-
* Delano (@solutious.com)
|
231
|
+
* [Delano Mandelbaum](http://delanotes.com/) (@solutious.com)
|
224
232
|
|
225
233
|
|
226
234
|
== License
|
data/Rakefile
CHANGED
@@ -3,15 +3,11 @@ require "rake"
|
|
3
3
|
require "rake/clean"
|
4
4
|
require 'yaml'
|
5
5
|
|
6
|
-
|
7
|
-
|
8
|
-
rescue LoadError
|
9
|
-
require 'rake/rdoctask'
|
10
|
-
end
|
11
|
-
|
6
|
+
require 'rdoc/task'
|
7
|
+
|
12
8
|
config = YAML.load_file("VERSION.yml")
|
13
9
|
task :default => ["build"]
|
14
|
-
CLEAN.include [ 'pkg', '
|
10
|
+
CLEAN.include [ 'pkg', 'rdoc' ]
|
15
11
|
name = "gibbler"
|
16
12
|
|
17
13
|
begin
|
@@ -20,22 +16,20 @@ begin
|
|
20
16
|
gem.version = "#{config[:MAJOR]}.#{config[:MINOR]}.#{config[:PATCH]}"
|
21
17
|
gem.name = name
|
22
18
|
gem.rubyforge_project = gem.name
|
23
|
-
gem.summary = "
|
24
|
-
gem.description =
|
19
|
+
gem.summary = "Git-like hashes for Ruby objects"
|
20
|
+
gem.description = "Git-like hashes for Ruby objects"
|
25
21
|
gem.email = "delano@solutious.com"
|
26
22
|
gem.homepage = "http://github.com/delano/gibbler"
|
27
23
|
gem.authors = ["Delano Mandelbaum"]
|
28
|
-
gem.add_dependency("attic", ">= 0.4.0")
|
29
24
|
end
|
30
25
|
Jeweler::GemcutterTasks.new
|
31
26
|
rescue LoadError
|
32
27
|
puts "Jeweler (or a dependency) not available. Install it with: sudo gem install jeweler"
|
33
28
|
end
|
34
29
|
|
35
|
-
|
36
|
-
Rake::RDocTask.new do |rdoc|
|
30
|
+
RDoc::Task.new do |rdoc|
|
37
31
|
version = "#{config[:MAJOR]}.#{config[:MINOR]}.#{config[:PATCH]}"
|
38
|
-
rdoc.rdoc_dir = "
|
32
|
+
rdoc.rdoc_dir = "rdoc"
|
39
33
|
rdoc.title = "#{name} #{version}"
|
40
34
|
rdoc.rdoc_files.include("README*")
|
41
35
|
rdoc.rdoc_files.include("LICENSE.txt")
|
@@ -43,22 +37,3 @@ Rake::RDocTask.new do |rdoc|
|
|
43
37
|
rdoc.rdoc_files.include("lib/**/*.rb")
|
44
38
|
end
|
45
39
|
|
46
|
-
|
47
|
-
# Rubyforge Release / Publish Tasks ==================================
|
48
|
-
|
49
|
-
#about 'Publish website to rubyforge'
|
50
|
-
task 'publish:rdoc' => 'doc/index.html' do
|
51
|
-
#sh "scp -rp doc/* rubyforge.org:/var/www/gforge-projects/#{name}/"
|
52
|
-
end
|
53
|
-
|
54
|
-
#about 'Public release to rubyforge'
|
55
|
-
task 'publish:gem' => [:package] do |t|
|
56
|
-
sh <<-end
|
57
|
-
rubyforge add_release -o Any -a CHANGES.txt -f -n README.md #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.gem &&
|
58
|
-
rubyforge add_file -o Any -a CHANGES.txt -f -n README.md #{name} #{name} #{@spec.version} pkg/#{name}-#{@spec.version}.tgz
|
59
|
-
end
|
60
|
-
end
|
61
|
-
|
62
|
-
|
63
|
-
|
64
|
-
|
data/VERSION.yml
CHANGED
data/gibbler.gemspec
CHANGED
@@ -1,57 +1,59 @@
|
|
1
1
|
# Generated by jeweler
|
2
2
|
# DO NOT EDIT THIS FILE DIRECTLY
|
3
|
-
# Instead, edit Jeweler::Tasks in Rakefile, and run
|
3
|
+
# Instead, edit Jeweler::Tasks in Rakefile, and run the gemspec command
|
4
4
|
# -*- encoding: utf-8 -*-
|
5
5
|
|
6
6
|
Gem::Specification.new do |s|
|
7
7
|
s.name = "gibbler"
|
8
|
-
s.version = "0.
|
8
|
+
s.version = "0.9.0"
|
9
9
|
|
10
10
|
s.required_rubygems_version = Gem::Requirement.new(">= 0") if s.respond_to? :required_rubygems_version=
|
11
11
|
s.authors = ["Delano Mandelbaum"]
|
12
|
-
s.date = "
|
12
|
+
s.date = "2012-04-20"
|
13
13
|
s.description = "Gibbler: Git-like hashes for Ruby objects"
|
14
14
|
s.email = "delano@solutious.com"
|
15
15
|
s.extra_rdoc_files = [
|
16
16
|
"LICENSE.txt",
|
17
|
-
|
17
|
+
"README.rdoc"
|
18
18
|
]
|
19
19
|
s.files = [
|
20
20
|
"CHANGES.txt",
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
21
|
+
"LICENSE.txt",
|
22
|
+
"README.rdoc",
|
23
|
+
"Rakefile",
|
24
|
+
"VERSION.yml",
|
25
|
+
"gibbler.gemspec",
|
26
|
+
"lib/gibbler.rb",
|
27
|
+
"lib/gibbler/aliases.rb",
|
28
|
+
"lib/gibbler/history.rb",
|
29
|
+
"lib/gibbler/mixins.rb",
|
30
|
+
"try/01_core_ext_try.rb",
|
31
|
+
"try/02_compat_try.rb",
|
32
|
+
"try/05_gibbler_digest_try.rb",
|
33
|
+
"try/10_standalone_try.rb",
|
34
|
+
"try/11_basic_try.rb",
|
35
|
+
"try/12_basic_sha256_try.rb",
|
36
|
+
"try/14_extended_try.rb",
|
37
|
+
"try/15_file_try.rb",
|
38
|
+
"try/16_uri_try.rb",
|
39
|
+
"try/17_complex_object_try.rb",
|
40
|
+
"try/18_proc_try.rb",
|
41
|
+
"try/20_time_try.rb",
|
42
|
+
"try/30_secret_try.rb",
|
43
|
+
"try/50_history_try.rb",
|
44
|
+
"try/51_hash_history_try.rb",
|
45
|
+
"try/52_array_history_try.rb",
|
46
|
+
"try/53_string_history_try.rb",
|
47
|
+
"try/57_arbitrary_history_try.rb",
|
48
|
+
"try/59_history_exceptions_try.rb",
|
49
|
+
"try/80_performance_try.rb",
|
50
|
+
"try/90_alias_try.rb"
|
50
51
|
]
|
51
52
|
s.homepage = "http://github.com/delano/gibbler"
|
53
|
+
s.rdoc_options = ["--charset=UTF-8"]
|
52
54
|
s.require_paths = ["lib"]
|
53
55
|
s.rubyforge_project = "gibbler"
|
54
|
-
s.rubygems_version = "1.8.
|
56
|
+
s.rubygems_version = "1.8.22"
|
55
57
|
s.summary = "Gibbler: Git-like hashes for Ruby objects"
|
56
58
|
|
57
59
|
if s.respond_to? :specification_version then
|
data/lib/gibbler.rb
CHANGED
@@ -14,7 +14,7 @@ require 'digest/sha1'
|
|
14
14
|
#
|
15
15
|
# "Hola, Tanneritos"
|
16
16
|
#
|
17
|
-
|
17
|
+
class Gibbler < String
|
18
18
|
module VERSION
|
19
19
|
def self.to_s
|
20
20
|
load_config
|
@@ -33,8 +33,6 @@ module Gibbler
|
|
33
33
|
attr_accessor :secret, :default_base
|
34
34
|
end
|
35
35
|
|
36
|
-
require 'gibbler/mixins'
|
37
|
-
|
38
36
|
class Error < RuntimeError
|
39
37
|
def initialize(obj); @obj = obj; end
|
40
38
|
end
|
@@ -47,87 +45,92 @@ end
|
|
47
45
|
#
|
48
46
|
class Gibbler::Digest < String
|
49
47
|
|
50
|
-
|
51
|
-
|
52
|
-
base
|
53
|
-
|
54
|
-
|
48
|
+
module InstanceMethods
|
49
|
+
# Return an integer assuming base is Gibbler.default_base.
|
50
|
+
def to_i(base=nil)
|
51
|
+
base ||= Gibbler.default_base
|
52
|
+
super(base)
|
53
|
+
end
|
55
54
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
55
|
+
# Returns a string. Takes an optional base.
|
56
|
+
def to_s(base=nil)
|
57
|
+
base.nil? ? super() : super().to_i(Gibbler.default_base).to_s(base)
|
58
|
+
end
|
60
59
|
|
61
|
-
|
62
|
-
|
63
|
-
|
60
|
+
def base(base=Gibbler.default_base)
|
61
|
+
v = self.to_i(Gibbler.default_base).to_s(base)
|
62
|
+
v.extend Gibbler::Digest::InstanceMethods
|
63
|
+
self.class.new v
|
64
|
+
end
|
64
65
|
|
65
|
-
|
66
|
-
|
67
|
-
|
66
|
+
def base36
|
67
|
+
base(36)
|
68
|
+
end
|
68
69
|
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
70
|
+
# Shorten the digest to the given (optional) length.
|
71
|
+
def shorten(len=20)
|
72
|
+
self[0..len-1]
|
73
|
+
end
|
73
74
|
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
75
|
+
# Returns the first 8 characters of itself (the digest).
|
76
|
+
#
|
77
|
+
# e.g.
|
78
|
+
#
|
79
|
+
# "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
80
|
+
# "kimmy".gibbler.short # => c8027100
|
81
|
+
#
|
82
|
+
def short
|
83
|
+
shorten(8)
|
84
|
+
end
|
84
85
|
|
85
|
-
|
86
|
-
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
86
|
+
# Returns the first 6 characters of itself (the digest).
|
87
|
+
#
|
88
|
+
# e.g.
|
89
|
+
#
|
90
|
+
# "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
91
|
+
# "kimmy".gibbler.shorter # => c80271
|
92
|
+
#
|
93
|
+
def shorter
|
94
|
+
shorten(6)
|
95
|
+
end
|
95
96
|
|
96
|
-
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
97
|
+
# Returns the first 4 characters of itself (the digest).
|
98
|
+
#
|
99
|
+
# e.g.
|
100
|
+
#
|
101
|
+
# "kimmy".gibbler # => c8027100ecc54945ab15ddac529230e38b1ba6a1
|
102
|
+
# "kimmy".gibbler.tiny # => c802
|
103
|
+
#
|
104
|
+
def tiny
|
105
|
+
shorten(4)
|
106
|
+
end
|
106
107
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
108
|
+
# Returns true when +ali+ matches +self+
|
109
|
+
#
|
110
|
+
# "kimmy".gibbler == "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
|
111
|
+
# "kimmy".gibbler == "c8027100" # => false
|
112
|
+
#
|
113
|
+
def ==(ali)
|
114
|
+
return true if self.to_s == ali.to_s
|
115
|
+
false
|
116
|
+
end
|
116
117
|
|
117
|
-
|
118
|
-
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
|
118
|
+
# Returns true when +g+ matches one of: +self+, +short+, +shorter+, +tiny+
|
119
|
+
#
|
120
|
+
# "kimmy".gibbler === "c8027100ecc54945ab15ddac529230e38b1ba6a1" # => true
|
121
|
+
# "kimmy".gibbler === "c8027100" # => true
|
122
|
+
# "kimmy".gibbler === "c80271" # => true
|
123
|
+
# "kimmy".gibbler === "c802" # => true
|
124
|
+
#
|
125
|
+
def ===(g)
|
126
|
+
return true if [to_s, short, shorter, tiny].member?(g.to_s)
|
127
|
+
false
|
128
|
+
end
|
127
129
|
end
|
130
|
+
include InstanceMethods
|
128
131
|
end
|
129
132
|
|
130
|
-
|
133
|
+
class Gibbler < String
|
131
134
|
module Object
|
132
135
|
|
133
136
|
def self.included(obj)
|
@@ -215,38 +218,70 @@ module Gibbler
|
|
215
218
|
|
216
219
|
end
|
217
220
|
|
221
|
+
class Gibbler < String
|
222
|
+
include Gibbler::Digest::InstanceMethods
|
223
|
+
# Modify the digest type for this instance. See Gibbler.digest_type
|
224
|
+
attr_writer :digest_type
|
225
|
+
attr_reader :input
|
226
|
+
# Creates a digest from the given +input+. See Gibbler.digest.
|
227
|
+
#
|
228
|
+
# If only one argument is given and it's a digest, this will
|
229
|
+
# simply create an instance of that digest. In other words,
|
230
|
+
# it won't calculate a new digest based on that input.
|
231
|
+
def initialize *input
|
232
|
+
if input.size == 1 && Gibbler::Digest::InstanceMethods === input.first
|
233
|
+
super input.first
|
234
|
+
else
|
235
|
+
input.collect!(&:to_s)
|
236
|
+
super Gibbler.digest(input) || ''
|
237
|
+
end
|
238
|
+
end
|
239
|
+
def digest_type
|
240
|
+
@digest_type || self.class.digest_type
|
241
|
+
end
|
242
|
+
|
243
|
+
def digest *input
|
244
|
+
replace Gibbler.digest(input, digest_type)
|
245
|
+
end
|
246
|
+
|
247
|
+
end
|
218
248
|
|
219
|
-
|
249
|
+
class Gibbler < String
|
220
250
|
|
221
|
-
|
222
|
-
|
251
|
+
@debug = false
|
252
|
+
@digest_type = ::Digest::SHA1
|
253
|
+
@delimiter = ':'
|
223
254
|
|
224
|
-
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
229
|
-
|
230
|
-
|
255
|
+
class << self
|
256
|
+
# Specify a different digest class. The default is +Digest::SHA1+. You
|
257
|
+
# could try +Digest::SHA256+ by doing this:
|
258
|
+
#
|
259
|
+
# Object.digest_type = Digest::SHA256
|
260
|
+
#
|
261
|
+
attr_accessor :digest_type
|
262
|
+
# The delimiter to use when joining Array values before creating a
|
263
|
+
# new digest hash. The default is ":".
|
264
|
+
attr_accessor :delimiter
|
265
|
+
# Set to true for debug output (including all digest inputs)
|
266
|
+
attr_accessor :debug
|
267
|
+
# Returns the current debug status (true or false)
|
268
|
+
def debug?; @debug != false; end
|
231
269
|
end
|
232
|
-
# Returns the current debug status (true or false)
|
233
|
-
def self.debug?; @@gibbler_debug; end
|
234
|
-
def self.enable_debug; @@gibbler_debug = true; end
|
235
|
-
def self.disable_debug; @@gibbler_debug = false; end
|
236
|
-
def self.debug=(v); @@gibbler_debug = v; end
|
237
|
-
# Returns the current digest class.
|
238
|
-
def self.digest_type; @@gibbler_digest_type; end
|
239
270
|
|
240
|
-
# Sends +
|
271
|
+
# Sends +input+ to Digest::SHA1.hexdigest. If another digest class
|
241
272
|
# has been specified, that class will be used instead.
|
242
273
|
# If Gibbler.secret is set, +str+ will be prepended with the
|
243
274
|
# value.
|
244
275
|
#
|
276
|
+
# If +input+ is an Array, it will be flattened and joined.
|
277
|
+
#
|
245
278
|
# See: digest_type
|
246
|
-
def self.digest(
|
247
|
-
|
248
|
-
|
249
|
-
|
279
|
+
def self.digest(input, digest_type=nil)
|
280
|
+
input = input.flatten.collect(&:to_s).join(delimiter) if ::Array === input
|
281
|
+
return if input.empty?
|
282
|
+
digest_type ||= @digest_type
|
283
|
+
input = [Gibbler.secret, input].join(delimiter) unless Gibbler.secret.nil?
|
284
|
+
dig = digest_type.hexdigest(input)
|
250
285
|
dig = dig.to_i(16).to_s(Gibbler.default_base) if 16 != Gibbler.default_base
|
251
286
|
dig
|
252
287
|
end
|
@@ -265,8 +300,9 @@ module Gibbler
|
|
265
300
|
raise "You probably want to include Gibbler::Complex or Gibbler::Object"
|
266
301
|
end
|
267
302
|
|
303
|
+
|
268
304
|
# Creates a digest based on:
|
269
|
-
# * An Array of instance variable names and values in the format: <tt>CLASS:LENGTH:VALUE</tt>
|
305
|
+
# * An Array of instance variable names or method names and values in the format: <tt>CLASS:LENGTH:VALUE</tt>
|
270
306
|
# * The gibbler method is called on each element so if it is a Hash or Array etc it
|
271
307
|
# will be parsed recursively according to the gibbler method for that class type.
|
272
308
|
# * Digest the Array of digests
|
@@ -324,14 +360,14 @@ module Gibbler
|
|
324
360
|
d = []
|
325
361
|
gibbler_debug :gibbler_fields, gibbler_fields
|
326
362
|
gibbler_fields.each do |n|
|
327
|
-
value = instance_variable_get("@#{n}")
|
363
|
+
value = respond_to?(n) ? send(n) : instance_variable_get("@#{n}")
|
328
364
|
unless value.respond_to? :__gibbler
|
329
365
|
gibbler_debug klass, :skipping, n
|
330
366
|
next
|
331
367
|
end
|
332
368
|
d << '%s:%s:%s' % [value.class, n, value.__gibbler(digest_type)]
|
333
369
|
end
|
334
|
-
d = d.join(
|
370
|
+
d = d.join(Gibbler.delimiter).__gibbler(digest_type)
|
335
371
|
a = Gibbler.digest "%s:%d:%s" % [klass, d.size, d], digest_type
|
336
372
|
gibbler_debug klass, a, [klass, d.size, d]
|
337
373
|
a
|
@@ -344,7 +380,6 @@ module Gibbler
|
|
344
380
|
self.instance_variable_set v
|
345
381
|
end
|
346
382
|
end
|
347
|
-
|
348
383
|
end
|
349
384
|
|
350
385
|
# Creates a digest based on: <tt>CLASS:LENGTH:VALUE</tt>.
|
@@ -417,7 +452,7 @@ module Gibbler
|
|
417
452
|
end
|
418
453
|
'%s:%s:%s' % [value.class, name, value.__gibbler(digest_type)]
|
419
454
|
end
|
420
|
-
d = d.join(
|
455
|
+
d = d.join(Gibbler.delimiter).__gibbler(digest_type)
|
421
456
|
a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d], digest_type
|
422
457
|
gibbler_debug klass, a, [klass, d.size, d]
|
423
458
|
a
|
@@ -461,7 +496,7 @@ module Gibbler
|
|
461
496
|
d << '%s:%s:%s' % [value.class, index, value.__gibbler(digest_type)]
|
462
497
|
index += 1
|
463
498
|
end
|
464
|
-
d = d.join(
|
499
|
+
d = d.join(Gibbler.delimiter).__gibbler(digest_type)
|
465
500
|
a = Gibbler.digest '%s:%s:%s' % [klass, d.size, d], digest_type
|
466
501
|
gibbler_debug klass, a, [klass, d.size, d]
|
467
502
|
a
|
@@ -652,34 +687,15 @@ module Gibbler
|
|
652
687
|
|
653
688
|
end
|
654
689
|
|
690
|
+
class String
|
691
|
+
unless method_defined? :clear
|
692
|
+
def clear
|
693
|
+
replace ""
|
694
|
+
end
|
695
|
+
end
|
696
|
+
end
|
655
697
|
|
656
|
-
class NilClass; include Gibbler::Nil; end
|
657
|
-
class Class; include Gibbler::Object; end
|
658
|
-
class Module; include Gibbler::Object; end
|
659
|
-
class Proc; include Gibbler::Object; end
|
660
|
-
class String; include Gibbler::String; end
|
661
|
-
class Regexp; include Gibbler::String; end
|
662
|
-
class Fixnum; include Gibbler::String; end
|
663
|
-
class Bignum; include Gibbler::String; end
|
664
|
-
class TrueClass; include Gibbler::String; end
|
665
|
-
class FalseClass; include Gibbler::String; end
|
666
|
-
class Float; include Gibbler::String; end
|
667
|
-
class Symbol; include Gibbler::String; end
|
668
|
-
class Date; include Gibbler::String; end
|
669
|
-
class Hash; include Gibbler::Hash; end
|
670
|
-
class Array; include Gibbler::Array; end
|
671
|
-
class Time; include Gibbler::Time; end
|
672
|
-
class DateTime < Date; include Gibbler::DateTime; end
|
673
|
-
class Range; include Gibbler::Range; end
|
674
|
-
class File; include Gibbler::File; end
|
675
|
-
class TempFile; include Gibbler::File; end
|
676
|
-
|
677
|
-
# URI::Generic must be included towards the
|
678
|
-
# end b/c it runs Object#freeze statically.
|
679
|
-
module URI; class Generic; include Gibbler::String; end; end
|
680
698
|
|
681
|
-
# Bundler calls freeze on an instance of Gem::Platform
|
682
|
-
module Gem; class Platform; include Gibbler::Complex; end; end
|
683
699
|
|
684
700
|
|
685
701
|
|
data/lib/gibbler/aliases.rb
CHANGED
data/lib/gibbler/history.rb
CHANGED
data/lib/gibbler/mixins.rb
CHANGED
@@ -1,9 +1,34 @@
|
|
1
|
+
require 'gibbler'
|
1
2
|
|
3
|
+
class NilClass; include Gibbler::Nil; end
|
4
|
+
class String; include Gibbler::String; end
|
5
|
+
class Symbol; include Gibbler::String; end
|
6
|
+
class Fixnum; include Gibbler::String; end
|
7
|
+
class Bignum; include Gibbler::String; end
|
8
|
+
class TrueClass; include Gibbler::String; end
|
9
|
+
class FalseClass; include Gibbler::String; end
|
10
|
+
class Class; include Gibbler::Object; end
|
11
|
+
class Module; include Gibbler::Object; end
|
12
|
+
class Proc; include Gibbler::Object; end
|
13
|
+
class Regexp; include Gibbler::String; end
|
14
|
+
class Float; include Gibbler::String; end
|
15
|
+
class Date; include Gibbler::String; end
|
16
|
+
class Hash; include Gibbler::Hash; end
|
17
|
+
class Array; include Gibbler::Array; end
|
18
|
+
class Time; include Gibbler::Time; end
|
19
|
+
class DateTime < Date; include Gibbler::DateTime; end
|
20
|
+
class Range; include Gibbler::Range; end
|
21
|
+
class File; include Gibbler::File; end
|
22
|
+
class TempFile; include Gibbler::File; end
|
23
|
+
class MatchData; include Gibbler::String; end
|
24
|
+
class OpenStruct; include Gibbler::Object; end
|
25
|
+
|
26
|
+
# URI::Generic must be included towards the
|
27
|
+
# end b/c it runs Object#freeze statically.
|
28
|
+
module URI; class Generic; include Gibbler::String; end; end
|
29
|
+
|
30
|
+
# Bundler calls freeze on an instance of Gem::Platform
|
31
|
+
module Gem; class Platform; include Gibbler::Complex; end; end
|
32
|
+
|
33
|
+
module Addressable; class URI; include Gibbler::String; end; end
|
2
34
|
|
3
|
-
class String
|
4
|
-
unless method_defined? :clear
|
5
|
-
def clear
|
6
|
-
replace ""
|
7
|
-
end
|
8
|
-
end
|
9
|
-
end
|
data/try/02_compat_try.rb
CHANGED
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'gibbler'
|
2
|
+
|
3
|
+
@sha256_digest = if Tryouts.sysinfo.vm == :java
|
4
|
+
require 'openssl'
|
5
|
+
OpenSSL::Digest::SHA256
|
6
|
+
else
|
7
|
+
Digest::SHA256
|
8
|
+
end
|
9
|
+
|
10
|
+
## Default delimiter
|
11
|
+
Gibbler.delimiter
|
12
|
+
#=> ':'
|
13
|
+
|
14
|
+
## Create a digest from flattened Array
|
15
|
+
Gibbler.digest [1, :sym, ['string', 2,3]].flatten.join(':')
|
16
|
+
#=> 'd84d6ad2bd5c9589842fb02cf3c384e4924b1d3f'
|
17
|
+
|
18
|
+
## Create a digest from Array
|
19
|
+
Gibbler.digest [1, :sym, ['string', 2,3]]
|
20
|
+
#=> 'd84d6ad2bd5c9589842fb02cf3c384e4924b1d3f'
|
21
|
+
|
22
|
+
## Create an instance
|
23
|
+
Gibbler.new 1, :sym, 'string', 2,3
|
24
|
+
#=> 'd84d6ad2bd5c9589842fb02cf3c384e4924b1d3f'
|
25
|
+
|
26
|
+
## Can modify base
|
27
|
+
g = Gibbler.new 1, :sym, 'string', 2,3
|
28
|
+
g.base(36)
|
29
|
+
#=> 'p9lffkbfkgpf7j71ho5cvxxcvx8gv27'
|
30
|
+
|
31
|
+
## Maintains class
|
32
|
+
g = Gibbler.new 1, :sym, 'string', 2,3
|
33
|
+
g.base(36).class
|
34
|
+
#=> Gibbler
|
35
|
+
|
36
|
+
## Can change digest type by class
|
37
|
+
Gibbler.digest_type = @sha256_digest
|
38
|
+
g = Gibbler.new 1, :sym, 'string', 2,3
|
39
|
+
#=> '204aacebb816bc2c8675f3490bf5a1a908988fb72f3dfd6774e963bbb9e26a26'
|
40
|
+
|
41
|
+
## Can change digest type per instance
|
42
|
+
Gibbler.digest_type = Digest::SHA1
|
43
|
+
g = Gibbler.new
|
44
|
+
g.digest_type = @sha256_digest
|
45
|
+
g.digest 1, :sym, 'string', 2,3
|
46
|
+
g
|
47
|
+
#=> '204aacebb816bc2c8675f3490bf5a1a908988fb72f3dfd6774e963bbb9e26a26'
|
48
|
+
|
49
|
+
Gibbler.digest_type = Digest::SHA1
|
data/try/14_extended_try.rb
CHANGED
data/try/15_file_try.rb
CHANGED
data/try/16_uri_try.rb
CHANGED
@@ -1,4 +1,5 @@
|
|
1
|
-
require 'gibbler'
|
1
|
+
require 'gibbler/mixins'
|
2
|
+
require 'time'
|
2
3
|
|
3
4
|
# arbitrary objects can specify instance variables to gibbler
|
4
5
|
class ::FullHouse
|
@@ -18,10 +19,12 @@ require 'gibbler'
|
|
18
19
|
# arbitrary objects can append more instance variables later on
|
19
20
|
class ::FullHouse
|
20
21
|
gibbler :stamp, :ready
|
22
|
+
def stamp
|
23
|
+
Time.parse('2009-08-25 16:43:53 UTC')
|
24
|
+
end
|
21
25
|
end
|
22
26
|
a = FullHouse.new
|
23
27
|
a.roles = [:jesse, :joey, :danny, :kimmy, :michelle, :dj, :stephanie]
|
24
|
-
a.stamp = Time.parse('2009-08-25 16:43:53 UTC')
|
25
28
|
a.ready = true
|
26
29
|
a.gibbler
|
27
30
|
#=> "fbdce0d97a856e7106bec418d585c914914b8aa5"
|
data/try/18_proc_try.rb
CHANGED
data/try/20_time_try.rb
CHANGED
data/try/30_secret_try.rb
CHANGED
data/try/50_history_try.rb
CHANGED
data/try/51_hash_history_try.rb
CHANGED
data/try/52_array_history_try.rb
CHANGED
metadata
CHANGED
@@ -1,38 +1,24 @@
|
|
1
|
-
--- !ruby/object:Gem::Specification
|
1
|
+
--- !ruby/object:Gem::Specification
|
2
2
|
name: gibbler
|
3
|
-
version: !ruby/object:Gem::Version
|
3
|
+
version: !ruby/object:Gem::Version
|
4
|
+
version: 0.9.0
|
4
5
|
prerelease:
|
5
|
-
version: 0.8.10
|
6
6
|
platform: ruby
|
7
|
-
authors:
|
7
|
+
authors:
|
8
8
|
- Delano Mandelbaum
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
- !ruby/object:Gem::Dependency
|
16
|
-
name: attic
|
17
|
-
prerelease: false
|
18
|
-
requirement: &id001 !ruby/object:Gem::Requirement
|
19
|
-
none: false
|
20
|
-
requirements:
|
21
|
-
- - ">="
|
22
|
-
- !ruby/object:Gem::Version
|
23
|
-
version: 0.4.0
|
24
|
-
type: :runtime
|
25
|
-
version_requirements: *id001
|
26
|
-
description: "Gibbler: Git-like hashes for Ruby objects"
|
12
|
+
date: 2013-01-08 00:00:00.000000000 Z
|
13
|
+
dependencies: []
|
14
|
+
description: Git-like hashes for Ruby objects
|
27
15
|
email: delano@solutious.com
|
28
16
|
executables: []
|
29
|
-
|
30
17
|
extensions: []
|
31
|
-
|
32
|
-
extra_rdoc_files:
|
18
|
+
extra_rdoc_files:
|
33
19
|
- LICENSE.txt
|
34
20
|
- README.rdoc
|
35
|
-
files:
|
21
|
+
files:
|
36
22
|
- CHANGES.txt
|
37
23
|
- LICENSE.txt
|
38
24
|
- README.rdoc
|
@@ -43,11 +29,12 @@ files:
|
|
43
29
|
- lib/gibbler/aliases.rb
|
44
30
|
- lib/gibbler/history.rb
|
45
31
|
- lib/gibbler/mixins.rb
|
46
|
-
- try/
|
32
|
+
- try/01_core_ext_try.rb
|
47
33
|
- try/02_compat_try.rb
|
48
34
|
- try/05_gibbler_digest_try.rb
|
49
|
-
- try/
|
50
|
-
- try/
|
35
|
+
- try/10_standalone_try.rb
|
36
|
+
- try/11_basic_try.rb
|
37
|
+
- try/12_basic_sha256_try.rb
|
51
38
|
- try/14_extended_try.rb
|
52
39
|
- try/15_file_try.rb
|
53
40
|
- try/16_uri_try.rb
|
@@ -65,30 +52,26 @@ files:
|
|
65
52
|
- try/90_alias_try.rb
|
66
53
|
homepage: http://github.com/delano/gibbler
|
67
54
|
licenses: []
|
68
|
-
|
69
55
|
post_install_message:
|
70
56
|
rdoc_options: []
|
71
|
-
|
72
|
-
require_paths:
|
57
|
+
require_paths:
|
73
58
|
- lib
|
74
|
-
required_ruby_version: !ruby/object:Gem::Requirement
|
59
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
75
60
|
none: false
|
76
|
-
requirements:
|
77
|
-
- -
|
78
|
-
- !ruby/object:Gem::Version
|
79
|
-
version:
|
80
|
-
required_rubygems_version: !ruby/object:Gem::Requirement
|
61
|
+
requirements:
|
62
|
+
- - ! '>='
|
63
|
+
- !ruby/object:Gem::Version
|
64
|
+
version: '0'
|
65
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
81
66
|
none: false
|
82
|
-
requirements:
|
83
|
-
- -
|
84
|
-
- !ruby/object:Gem::Version
|
85
|
-
version:
|
67
|
+
requirements:
|
68
|
+
- - ! '>='
|
69
|
+
- !ruby/object:Gem::Version
|
70
|
+
version: '0'
|
86
71
|
requirements: []
|
87
|
-
|
88
72
|
rubyforge_project: gibbler
|
89
73
|
rubygems_version: 1.8.10
|
90
74
|
signing_key:
|
91
75
|
specification_version: 3
|
92
|
-
summary:
|
76
|
+
summary: Git-like hashes for Ruby objects
|
93
77
|
test_files: []
|
94
|
-
|