ruby-nuggets 0.6.8 → 0.6.9
Sign up to get free protection for your applications and to get access to all the features.
- data/.rspec +0 -1
- data/README +1 -1
- data/Rakefile +1 -1
- data/lib/nuggets/file/sub_mixin.rb +4 -4
- data/lib/nuggets/hash/deep_merge.rb +5 -0
- data/lib/nuggets/hash/deep_merge_mixin.rb +54 -0
- data/lib/nuggets/string/evaluate_mixin.rb +8 -5
- data/lib/nuggets/version.rb +1 -1
- data/spec/nuggets/file/replace_spec.rb +104 -0
- data/spec/nuggets/file/sub_spec.rb +158 -0
- data/spec/nuggets/hash/deep_merge_spec.rb +80 -0
- metadata +11 -6
data/.rspec
CHANGED
data/README
CHANGED
data/Rakefile
CHANGED
@@ -42,7 +42,7 @@ module Nuggets
|
|
42
42
|
# +block+ and returns the new content.
|
43
43
|
def sub(name, *args)
|
44
44
|
content = read(name)
|
45
|
-
content.sub!(*args, &block_given? ? Proc.new : nil)
|
45
|
+
content.sub!(*args, &block_given? ? ::Proc.new : nil)
|
46
46
|
content
|
47
47
|
end
|
48
48
|
|
@@ -56,7 +56,7 @@ module Nuggets
|
|
56
56
|
res = nil
|
57
57
|
|
58
58
|
replace(name) { |content|
|
59
|
-
res = content.sub!(*args, &block_given? ? Proc.new : nil)
|
59
|
+
res = content.sub!(*args, &block_given? ? ::Proc.new : nil)
|
60
60
|
content
|
61
61
|
}
|
62
62
|
|
@@ -70,7 +70,7 @@ module Nuggets
|
|
70
70
|
# +block+ and returns the new content.
|
71
71
|
def gsub(name, *args)
|
72
72
|
content = read(name)
|
73
|
-
content.gsub!(*args, &block_given? ? Proc.new : nil)
|
73
|
+
content.gsub!(*args, &block_given? ? ::Proc.new : nil)
|
74
74
|
content
|
75
75
|
end
|
76
76
|
|
@@ -84,7 +84,7 @@ module Nuggets
|
|
84
84
|
res = nil
|
85
85
|
|
86
86
|
replace(name) { |content|
|
87
|
-
res = content.gsub!(*args, &block_given? ? Proc.new : nil)
|
87
|
+
res = content.gsub!(*args, &block_given? ? ::Proc.new : nil)
|
88
88
|
content
|
89
89
|
}
|
90
90
|
|
@@ -0,0 +1,54 @@
|
|
1
|
+
#--
|
2
|
+
###############################################################################
|
3
|
+
# #
|
4
|
+
# A component of ruby-nuggets, some extensions to the Ruby programming #
|
5
|
+
# language. #
|
6
|
+
# #
|
7
|
+
# Copyright (C) 2007-2011 Jens Wille #
|
8
|
+
# #
|
9
|
+
# Authors: #
|
10
|
+
# Jens Wille <jens.wille@uni-koeln.de> #
|
11
|
+
# #
|
12
|
+
# ruby-nuggets is free software; you can redistribute it and/or modify it #
|
13
|
+
# under the terms of the GNU General Public License as published by the Free #
|
14
|
+
# Software Foundation; either version 3 of the License, or (at your option) #
|
15
|
+
# any later version. #
|
16
|
+
# #
|
17
|
+
# ruby-nuggets is distributed in the hope that it will be useful, but WITHOUT #
|
18
|
+
# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or #
|
19
|
+
# FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for #
|
20
|
+
# more details. #
|
21
|
+
# #
|
22
|
+
# You should have received a copy of the GNU General Public License along #
|
23
|
+
# with ruby-nuggets. If not, see <http://www.gnu.org/licenses/>. #
|
24
|
+
# #
|
25
|
+
###############################################################################
|
26
|
+
#++
|
27
|
+
|
28
|
+
module Nuggets
|
29
|
+
class Hash
|
30
|
+
module DeepMergeMixin
|
31
|
+
|
32
|
+
# call-seq:
|
33
|
+
# hash.deep_merge(other_hash) => aHash
|
34
|
+
#
|
35
|
+
# Merges nested hashes recursively (see Hash#merge).
|
36
|
+
def deep_merge(other)
|
37
|
+
merge(other) { |key, old, new|
|
38
|
+
old.respond_to?(:deep_merge) ? old.deep_merge(new) : new
|
39
|
+
}
|
40
|
+
end
|
41
|
+
|
42
|
+
# call-seq:
|
43
|
+
# hash.deep_merge!(other_hash) => hash
|
44
|
+
#
|
45
|
+
# Destructive version of #deep_merge.
|
46
|
+
def deep_merge!(other)
|
47
|
+
replace(deep_merge(other))
|
48
|
+
end
|
49
|
+
|
50
|
+
alias_method :deep_update, :deep_merge!
|
51
|
+
|
52
|
+
end
|
53
|
+
end
|
54
|
+
end
|
@@ -30,14 +30,17 @@ module Nuggets
|
|
30
30
|
module EvaluateMixin
|
31
31
|
|
32
32
|
# call-seq:
|
33
|
-
# str.evaluate(binding
|
33
|
+
# str.evaluate([binding, [filename, [lineno]]]) => new_str
|
34
34
|
#
|
35
35
|
# Basically turns Kernel#eval into an instance method of String -- inspired
|
36
36
|
# by Ruby Cookbook example 1.3. This allows to pre-populate strings with
|
37
|
-
# substitution expressions
|
38
|
-
# environment (= +binding+) at a later point.
|
39
|
-
|
40
|
-
|
37
|
+
# substitution expressions <tt>"#{...}"</tt> that can get evaluated in a
|
38
|
+
# different environment (= +binding+) at a later point.
|
39
|
+
#
|
40
|
+
# Passes optional arguments +filename+ and +lineno+ on to Kernel#eval.
|
41
|
+
def evaluate(binding = TOPLEVEL_BINDING, filename = nil, lineno = nil)
|
42
|
+
buffer = gsub(/\\*"/) { |m| "#{"\\" * m.length}#{m}" }
|
43
|
+
eval(%Q{"#{buffer}"}, binding, filename || __FILE__, lineno || __LINE__)
|
41
44
|
end
|
42
45
|
|
43
46
|
end
|
data/lib/nuggets/version.rb
CHANGED
@@ -0,0 +1,104 @@
|
|
1
|
+
require 'nuggets/file/replace'
|
2
|
+
require 'nuggets/tempfile/open'
|
3
|
+
|
4
|
+
describe File, 'when extended by', Nuggets::File::ReplaceMixin do
|
5
|
+
|
6
|
+
it { (class << File; ancestors; end).should include(Nuggets::File::ReplaceMixin) }
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@txt = <<-EOT.freeze
|
10
|
+
The fox went out on a chilly night
|
11
|
+
Prayed for the moon to give him light
|
12
|
+
For he had many a mile to go that night
|
13
|
+
Before he reached the town o
|
14
|
+
EOT
|
15
|
+
|
16
|
+
@res1 = <<-EOT.freeze
|
17
|
+
He ran til he came to a great big bin
|
18
|
+
Where the ducks and the geese were kept therein
|
19
|
+
Said, a couple of you are going to grease my chin
|
20
|
+
Before I leave this town o
|
21
|
+
EOT
|
22
|
+
|
23
|
+
@res2 = <<-EOT.freeze
|
24
|
+
THE FOX WENT OUT ON A CHILLY NIGHT
|
25
|
+
PRAYED FOR THE MOON TO GIVE HIM LIGHT
|
26
|
+
FOR HE HAD MANY A MILE TO GO THAT NIGHT
|
27
|
+
BEFORE HE REACHED THE TOWN O
|
28
|
+
EOT
|
29
|
+
end
|
30
|
+
|
31
|
+
example do
|
32
|
+
tempfile { |path|
|
33
|
+
res = File.replace(path) { @res1 }
|
34
|
+
res.should == @res1
|
35
|
+
File.read(path).should == @res1
|
36
|
+
}
|
37
|
+
end
|
38
|
+
|
39
|
+
example do
|
40
|
+
tempfile { |path|
|
41
|
+
res = File.replace(path) { |content| content }
|
42
|
+
res.should == @txt
|
43
|
+
File.read(path).should == @txt
|
44
|
+
}
|
45
|
+
end
|
46
|
+
|
47
|
+
example do
|
48
|
+
tempfile { |path|
|
49
|
+
res = File.replace(path) { |content| @res1 }
|
50
|
+
res.should == @res1
|
51
|
+
File.read(path).should == @res1
|
52
|
+
}
|
53
|
+
end
|
54
|
+
|
55
|
+
example do
|
56
|
+
tempfile { |path|
|
57
|
+
res = File.replace(path) { |content| content.upcase }
|
58
|
+
res.should == @res2
|
59
|
+
File.read(path).should == @res2
|
60
|
+
}
|
61
|
+
end
|
62
|
+
|
63
|
+
example do
|
64
|
+
lambda { File.replace(tempfile) { @res1 } }.should raise_error(Errno::ENOENT)
|
65
|
+
end
|
66
|
+
|
67
|
+
example do
|
68
|
+
begin
|
69
|
+
res = File.replace(path = tempfile, true) { @res1 }
|
70
|
+
res.should == @res1
|
71
|
+
File.read(path).should == @res1
|
72
|
+
ensure
|
73
|
+
File.unlink(path) if path
|
74
|
+
end
|
75
|
+
end
|
76
|
+
|
77
|
+
example do
|
78
|
+
begin
|
79
|
+
res = File.replace(path = tempfile, true) { |content| content }
|
80
|
+
res.should == ''
|
81
|
+
File.read(path).should == ''
|
82
|
+
ensure
|
83
|
+
File.unlink(path) if path
|
84
|
+
end
|
85
|
+
end
|
86
|
+
|
87
|
+
example do
|
88
|
+
begin
|
89
|
+
res = File.replace(path = tempfile, true) { |content| @res1 }
|
90
|
+
res.should == @res1
|
91
|
+
File.read(path).should == @res1
|
92
|
+
ensure
|
93
|
+
File.unlink(path) if path
|
94
|
+
end
|
95
|
+
end
|
96
|
+
|
97
|
+
def tempfile
|
98
|
+
t = Tempfile.open('nuggets_file_replace_spec_temp') { |f| f.puts @txt }
|
99
|
+
block_given? ? yield(t.path) : t.path
|
100
|
+
ensure
|
101
|
+
t.close(true) if t
|
102
|
+
end
|
103
|
+
|
104
|
+
end
|
@@ -0,0 +1,158 @@
|
|
1
|
+
require 'nuggets/file/sub'
|
2
|
+
require 'nuggets/tempfile/open'
|
3
|
+
|
4
|
+
describe File, 'when extended by', Nuggets::File::SubMixin do
|
5
|
+
|
6
|
+
it { (class << File; ancestors; end).should include(Nuggets::File::SubMixin) }
|
7
|
+
|
8
|
+
before :each do
|
9
|
+
@txt = <<-EOT.freeze
|
10
|
+
The fox went out on a chilly night
|
11
|
+
Prayed for the moon to give him light
|
12
|
+
For he had many a mile to go that night
|
13
|
+
Before he reached the town o
|
14
|
+
EOT
|
15
|
+
|
16
|
+
@res1 = <<-EOT.freeze
|
17
|
+
The fox went out on a chilly nXIGHTX
|
18
|
+
Prayed for the moon to give him light
|
19
|
+
For he had many a mile to go that night
|
20
|
+
Before he reached the town o
|
21
|
+
EOT
|
22
|
+
|
23
|
+
@res2 = <<-EOT.freeze
|
24
|
+
The fox went out on a chilly nXIGHTX
|
25
|
+
Prayed for the moon to give him lXIGHTX
|
26
|
+
For he had many a mile to go that nXIGHTX
|
27
|
+
Before he reached the town o
|
28
|
+
EOT
|
29
|
+
end
|
30
|
+
|
31
|
+
example do
|
32
|
+
tempfile { |path|
|
33
|
+
res = File.sub(path, /ight/, 'XIGHTX')
|
34
|
+
res.should == @res1
|
35
|
+
@txt.should_not == @res1
|
36
|
+
File.read(path).should == @txt
|
37
|
+
}
|
38
|
+
end
|
39
|
+
|
40
|
+
example do
|
41
|
+
tempfile { |path|
|
42
|
+
res = File.sub(path, /XightX/, 'xIGHTx')
|
43
|
+
res.should == @txt
|
44
|
+
File.read(path).should == @txt
|
45
|
+
}
|
46
|
+
end
|
47
|
+
|
48
|
+
example do
|
49
|
+
tempfile { |path|
|
50
|
+
res = File.sub(path, /ight/) { |m| "X#{m.upcase}X" }
|
51
|
+
res.should == @res1
|
52
|
+
@txt.should_not == @res1
|
53
|
+
File.read(path).should == @txt
|
54
|
+
}
|
55
|
+
end
|
56
|
+
|
57
|
+
example do
|
58
|
+
tempfile { |path|
|
59
|
+
res = File.sub(path, /XightX/) { |m| "x#{m.upcase}x" }
|
60
|
+
res.should == @txt
|
61
|
+
File.read(path).should == @txt
|
62
|
+
}
|
63
|
+
end
|
64
|
+
|
65
|
+
example do
|
66
|
+
tempfile { |path|
|
67
|
+
res = File.gsub(path, /ight/, 'XIGHTX')
|
68
|
+
res.should == @res2
|
69
|
+
@txt.should_not == @res2
|
70
|
+
File.read(path).should == @txt
|
71
|
+
}
|
72
|
+
end
|
73
|
+
|
74
|
+
example do
|
75
|
+
tempfile { |path|
|
76
|
+
res = File.gsub(path, /ight/) { |m| "X#{m.upcase}X" }
|
77
|
+
res.should == @res2
|
78
|
+
@txt.should_not == @res2
|
79
|
+
File.read(path).should == @txt
|
80
|
+
}
|
81
|
+
end
|
82
|
+
|
83
|
+
example do
|
84
|
+
tempfile { |path|
|
85
|
+
res = File.sub!(path, /ight/, 'XIGHTX')
|
86
|
+
res.should == @res1
|
87
|
+
@txt.should_not == @res1
|
88
|
+
File.read(path).should == @res1
|
89
|
+
}
|
90
|
+
end
|
91
|
+
|
92
|
+
example do
|
93
|
+
tempfile { |path|
|
94
|
+
res = File.sub!(path, /XightX/, 'xIGHTx')
|
95
|
+
res.should be_nil
|
96
|
+
File.read(path).should == @txt
|
97
|
+
}
|
98
|
+
end
|
99
|
+
|
100
|
+
example do
|
101
|
+
tempfile { |path|
|
102
|
+
res = File.sub!(path, /ight/) { |m| "X#{m.upcase}X" }
|
103
|
+
res.should == @res1
|
104
|
+
@txt.should_not == @res1
|
105
|
+
File.read(path).should == @res1
|
106
|
+
}
|
107
|
+
end
|
108
|
+
|
109
|
+
example do
|
110
|
+
tempfile { |path|
|
111
|
+
res = File.sub!(path, /XightX/) { |m| "x#{m.upcase}x" }
|
112
|
+
res.should be_nil
|
113
|
+
File.read(path).should == @txt
|
114
|
+
}
|
115
|
+
end
|
116
|
+
|
117
|
+
example do
|
118
|
+
tempfile { |path|
|
119
|
+
res = File.gsub!(path, /ight/, 'XIGHTX')
|
120
|
+
res.should == @res2
|
121
|
+
@txt.should_not == @res2
|
122
|
+
File.read(path).should == @res2
|
123
|
+
}
|
124
|
+
end
|
125
|
+
|
126
|
+
example do
|
127
|
+
tempfile { |path|
|
128
|
+
res = File.gsub!(path, /ight/) { |m| "X#{m.upcase}X" }
|
129
|
+
res.should == @res2
|
130
|
+
@txt.should_not == @res2
|
131
|
+
File.read(path).should == @res2
|
132
|
+
}
|
133
|
+
end
|
134
|
+
|
135
|
+
example do
|
136
|
+
lambda { File.sub(tempfile, /ight/, 'XIGHTX') }.should raise_error(Errno::ENOENT)
|
137
|
+
end
|
138
|
+
|
139
|
+
example do
|
140
|
+
lambda { File.sub!(tempfile, /ight/, 'XIGHTX') }.should raise_error(Errno::ENOENT)
|
141
|
+
end
|
142
|
+
|
143
|
+
example do
|
144
|
+
lambda { File.gsub(tempfile, /ight/, 'XIGHTX') }.should raise_error(Errno::ENOENT)
|
145
|
+
end
|
146
|
+
|
147
|
+
example do
|
148
|
+
lambda { File.gsub!(tempfile, /ight/, 'XIGHTX') }.should raise_error(Errno::ENOENT)
|
149
|
+
end
|
150
|
+
|
151
|
+
def tempfile
|
152
|
+
t = Tempfile.open('nuggets_file_sub_spec_temp') { |f| f.puts @txt }
|
153
|
+
block_given? ? yield(t.path) : t.path
|
154
|
+
ensure
|
155
|
+
t.close(true) if t
|
156
|
+
end
|
157
|
+
|
158
|
+
end
|
@@ -0,0 +1,80 @@
|
|
1
|
+
require 'nuggets/hash/deep_merge'
|
2
|
+
|
3
|
+
describe Hash, 'when extended by', Nuggets::Hash::DeepMergeMixin do
|
4
|
+
|
5
|
+
it { Hash.ancestors.should include(Nuggets::Hash::DeepMergeMixin) }
|
6
|
+
|
7
|
+
example do
|
8
|
+
{ :a => 1 }.deep_merge(:a => 2).should == { :a => 2 }
|
9
|
+
end
|
10
|
+
|
11
|
+
example do
|
12
|
+
{ :a => 1 }.deep_merge(:b => 2).should == { :a => 1, :b => 2 }
|
13
|
+
end
|
14
|
+
|
15
|
+
example do
|
16
|
+
{ :a => { :b => 1 } }.deep_merge(:b => 2).should == { :a => { :b => 1 }, :b => 2 }
|
17
|
+
end
|
18
|
+
|
19
|
+
example do
|
20
|
+
{ :a => { :b => 1 } }.deep_merge(:a => { :b => 2 }).should == { :a => { :b => 2 } }
|
21
|
+
end
|
22
|
+
|
23
|
+
example do
|
24
|
+
lambda { { :a => { :b => { :c => 1 } } }.deep_merge(:a => { :b => 2 }) }.should raise_error(TypeError)
|
25
|
+
end
|
26
|
+
|
27
|
+
example do
|
28
|
+
{ :a => { :b => { :c => 1 } } }.deep_merge(:a => { :b => { :c => 2 } }).should == { :a => { :b => { :c => 2 } } }
|
29
|
+
end
|
30
|
+
|
31
|
+
example do
|
32
|
+
{ :a => { :b => { :c => 1 } } }.deep_merge(:a => { :b => { :d => 2 } }).should == { :a => { :b => { :c => 1, :d => 2 } } }
|
33
|
+
end
|
34
|
+
|
35
|
+
example do
|
36
|
+
{ :a => { :b => { :c => 1 } } }.deep_merge(:a => { :b => { :c => 2 }, :d => 3 }).should == { :a => { :b => { :c => 2 }, :d => 3 } }
|
37
|
+
end
|
38
|
+
|
39
|
+
example do
|
40
|
+
{ :a => { :b => { :c => 1 }, :d => 2 } }.deep_merge(:a => { :b => { :c => 2 }, :d => 3 }).should == { :a => { :b => { :c => 2 }, :d => 3 } }
|
41
|
+
end
|
42
|
+
|
43
|
+
example do
|
44
|
+
{ :a => { :b => { :c => 1 }, :d => 2 }, :e => 3 }.deep_merge(:a => { :b => { :c => 2 }, :d => 3 }).should == { :a => { :b => { :c => 2 }, :d => 3 }, :e => 3 }
|
45
|
+
end
|
46
|
+
|
47
|
+
example do
|
48
|
+
{ :a => { :b => { :c => 1 } }, :d => { :e => 3 } }.deep_merge(:a => { :b => { :c => 2 } }, :d => { :e => 4 }).should == { :a => { :b => { :c => 2 } }, :d => { :e => 4 } }
|
49
|
+
end
|
50
|
+
|
51
|
+
context do
|
52
|
+
|
53
|
+
before :each do
|
54
|
+
@sub_hash1 = { :b => 1 }
|
55
|
+
@sub_hash2 = { :b => 2 }
|
56
|
+
|
57
|
+
@hash1 = { :a => @sub_hash1 }
|
58
|
+
@hash2 = { :a => @sub_hash2 }
|
59
|
+
@hash3 = { :a => { :b => 2} }
|
60
|
+
end
|
61
|
+
|
62
|
+
example do
|
63
|
+
@hash1.deep_merge(@hash2).should == @hash3
|
64
|
+
@hash1.should_not == @hash3
|
65
|
+
|
66
|
+
@sub_hash1[:b].should == 1
|
67
|
+
@sub_hash2[:b].should == 2
|
68
|
+
end
|
69
|
+
|
70
|
+
example do
|
71
|
+
@hash1.deep_merge!(@hash2).should == @hash3
|
72
|
+
@hash1.should == @hash3
|
73
|
+
|
74
|
+
@sub_hash1[:b].should == 1
|
75
|
+
@sub_hash2[:b].should == 2
|
76
|
+
end
|
77
|
+
|
78
|
+
end
|
79
|
+
|
80
|
+
end
|
metadata
CHANGED
@@ -1,13 +1,13 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: ruby-nuggets
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
hash:
|
4
|
+
hash: 21
|
5
5
|
prerelease:
|
6
6
|
segments:
|
7
7
|
- 0
|
8
8
|
- 6
|
9
|
-
-
|
10
|
-
version: 0.6.
|
9
|
+
- 9
|
10
|
+
version: 0.6.9
|
11
11
|
platform: ruby
|
12
12
|
authors:
|
13
13
|
- Jens Wille
|
@@ -15,7 +15,7 @@ autorequire:
|
|
15
15
|
bindir: bin
|
16
16
|
cert_chain: []
|
17
17
|
|
18
|
-
date: 2011-02-
|
18
|
+
date: 2011-02-11 00:00:00 +01:00
|
19
19
|
default_executable:
|
20
20
|
dependencies: []
|
21
21
|
|
@@ -67,6 +67,8 @@ files:
|
|
67
67
|
- lib/nuggets/hash/insert.rb
|
68
68
|
- lib/nuggets/hash/unroll.rb
|
69
69
|
- lib/nuggets/hash/unroll_mixin.rb
|
70
|
+
- lib/nuggets/hash/deep_merge_mixin.rb
|
71
|
+
- lib/nuggets/hash/deep_merge.rb
|
70
72
|
- lib/nuggets/hash/nest.rb
|
71
73
|
- lib/nuggets/hash/at.rb
|
72
74
|
- lib/nuggets/hash/in_order.rb
|
@@ -146,7 +148,10 @@ files:
|
|
146
148
|
- spec/nuggets/proc/bind_spec.rb
|
147
149
|
- spec/nuggets/hash/unroll_spec.rb
|
148
150
|
- spec/nuggets/hash/nest_spec.rb
|
151
|
+
- spec/nuggets/hash/deep_merge_spec.rb
|
149
152
|
- spec/nuggets/file/which_spec.rb
|
153
|
+
- spec/nuggets/file/replace_spec.rb
|
154
|
+
- spec/nuggets/file/sub_spec.rb
|
150
155
|
- spec/nuggets/string/evaluate_spec.rb
|
151
156
|
- spec/nuggets/string/xor_spec.rb
|
152
157
|
- spec/nuggets/string/wc_spec.rb
|
@@ -175,7 +180,7 @@ rdoc_options:
|
|
175
180
|
- --all
|
176
181
|
- --line-numbers
|
177
182
|
- --title
|
178
|
-
- ruby-nuggets Application documentation (v0.6.
|
183
|
+
- ruby-nuggets Application documentation (v0.6.9)
|
179
184
|
- --inline-source
|
180
185
|
require_paths:
|
181
186
|
- lib
|
@@ -200,7 +205,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
200
205
|
requirements: []
|
201
206
|
|
202
207
|
rubyforge_project: prometheus
|
203
|
-
rubygems_version: 1.5.
|
208
|
+
rubygems_version: 1.5.2
|
204
209
|
signing_key:
|
205
210
|
specification_version: 3
|
206
211
|
summary: Some extensions to the Ruby programming language.
|