summaryse 1.0.0 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,4 +1,50 @@
1
- # 1.0.0 / FIX ME
1
+ # 1.1.0 / FIX ME
2
+
3
+ * Added a way to register user-defined aggregation functions:
4
+
5
+ Summaryse.register(:comma_join) do |ary|
6
+ ary.join(', ')
7
+ end
8
+ [1, 4, 12, 7].summaryse(:comma_join)
9
+ # => "1, 4, 12, 7"
10
+
11
+ * Added the ability to specify aggregations on hash keys that are not used at
12
+ all. In this case, the aggregator is called on an empty array.
13
+
14
+ [
15
+ { :size => 12 },
16
+ { :size => 17 }
17
+ ].summaryse(:size => :max, :hobbies => lambda{|a| a})
18
+ # => {:size => 17, :hobbies => []}
19
+
20
+ * Added the ability to use objects responding to to_summaryse as aggregator
21
+ functions:
22
+
23
+ class Foo
24
+ def to_summaryse; :sum; end
25
+ end
26
+ [1, 2, 3].summaryse(Foo.new)
27
+ # => 6
28
+
29
+ * Added the ability to explicitly bypass Hash entries as the result of a
30
+ computation, by returning Summaryse::BYPASS
31
+
32
+ [
33
+ { :hobbies => [:ruby], :size => 12 },
34
+ { :hobbies => [:music], :size => 17 }
35
+ ].summaryse(:size => :max, :hobbies => lambda{|a| Summaryse::BYPASS})
36
+ # => {:size => 17}
37
+
38
+ * The semantics of aggregating empty arrays is guaranteed. Due to duck typing,
39
+ nil is returned in almost all cases except :count so far. This is specified
40
+ in README.
41
+
42
+ * Best-effort for yielding friendly hash ordering under ruby >= 1.9
43
+
44
+ * Array#summaryse now raises an ArgumentError when it does not understand its
45
+ aggregator argument.
46
+
47
+ # 1.0.0 / 2011.07.11
2
48
 
3
49
  * Enhancements
4
50
 
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- summaryse (1.0.0)
4
+ summaryse (1.1.0)
5
5
 
6
6
  GEM
7
7
  remote: http://rubygems.org/
data/README.md CHANGED
@@ -1,4 +1,4 @@
1
- # Array#summaryse
1
+ # Array#summaryse (version 1.1.0)
2
2
 
3
3
  [sudo] gem install summaryse
4
4
 
@@ -24,9 +24,9 @@ used to merge YAML files. Simpler examples are given a bit later.
24
24
  In many projects of mine including
25
25
  {https://github.com/blambeau/noe noe},
26
26
  {https://github.com/blambeau/agora agora} or
27
- {https://github.com/blambeau/dbagile dbagile}, a common need is merge YAML files.
28
- Merging YAML files is complex because you need full control of how merging applies
29
- on specific tree nodes. Summaryse solves this very effectively.
27
+ {https://github.com/blambeau/dbagile dbagile}, a common need is to merge YAML
28
+ files. Merging YAML files is difficult because you need full control of how
29
+ merging applies on specific tree nodes. Summaryse solves this very effectively.
30
30
 
31
31
  # This is left.yaml
32
32
  left = YAML.load ... # syntactically wrong, but to avoid Yard's rewriting
@@ -142,18 +142,16 @@ behavior to use on others:
142
142
  ].summaryse(:hobbies => :union, nil => :first)
143
143
  # => {:hobbies => [:ruby, :music], :size => 12}
144
144
 
145
- ### Specifying with lambdas
145
+ ### Unexisting keys
146
146
 
147
- When no default summarization function fit your needs, just pass a lambda. It
148
- will be called with the array of values on which aggregation must be done:
147
+ Specifying unexisting keys is also permitted. In this case, the evaluation is
148
+ done on an empty array:
149
149
 
150
150
  [
151
151
  { :hobbies => [:ruby], :size => 12 },
152
152
  { :hobbies => [:music], :size => 17 }
153
- ].summaryse(:hobbies => :union, :size => lambda{|a|
154
- a.join(', ')
155
- })
156
- # => {:hobbies => [:ruby, :music], :size => "12, 17"}
153
+ ].summaryse(:hello => lambda{|a| a})
154
+ # => {:hello => []}
157
155
 
158
156
  ## On Arrays of Hash-es
159
157
 
@@ -177,18 +175,85 @@ returned hashes are in order of encountered 'by key' values. That is, in the
177
175
  example above, yard comes before summaryse that comes before treetop because
178
176
  this is the order in which they have been seen initially.
179
177
 
180
- # By the way, why this stupid name?
178
+ # Some extra goodness
181
179
 
182
- Just because summarize was already an {https://rubygems.org/gems/summarize existing gem}.
183
- Summaryse is also much less likely to cause a name clash on the Array class. And
184
- I'm a french-speaking developer :-)
180
+ ## On empty arrays
185
181
 
186
- And where does 'summarize' come from? The name is inspired by (yet not equivalent
187
- to) {http://en.wikipedia.org/wiki/D_(data_language_specification)#Tutorial_D
188
- TUTORIAL D}'s summarization operator on relations.
189
- See my {https://github.com/blambeau/alf alf} project. Array#summaryse is
190
- rubyiesque in mind and does not conform to a purely relational vision of
191
- summarization, though.
182
+ For now, no special support is provided for the corner cases. One could argue
183
+ that the sum of an empty array should be 0, but this is wrong because of duck
184
+ typing (maybe you try to sum something else)... A nil value is returned in
185
+ almost all empty cases unless the semantics is very clear:
186
+
187
+ [].summaryse(:count) # => 0
188
+ [].summaryse(:sum) # => nil
189
+ [].summaryse(:avg) # => nil
190
+
191
+ [].summaryse(:min) # => nil
192
+ [].summaryse(:max) # => nil
193
+ [].summaryse(:first) # => nil
194
+ [].summaryse(:last) # => nil
195
+
196
+ [].summaryse(:intersection) # => nil
197
+ [].summaryse(:union) # => nil
198
+
199
+ Special support for specifying a default value to use on empty arrays should
200
+ be provided around 2.0. Don't hesitate too contribute a patch if you need it
201
+ earlier.
202
+
203
+ ## Specifying with lambdas
204
+
205
+ When no default summarization function fit your needs, just pass a lambda. It
206
+ will be called with the array of values on which aggregation must be done:
207
+
208
+ [
209
+ { :hobbies => [:ruby], :size => 12 },
210
+ { :hobbies => [:music], :size => 17 }
211
+ ].summaryse(:hobbies => :union, :size => lambda{|a|
212
+ a.join(', ')
213
+ })
214
+ # => {:hobbies => [:ruby, :music], :size => "12, 17"}
215
+
216
+ ## Registering your own aggregators
217
+
218
+ Since 1.1, you can register your own aggregation functions. Such function simply
219
+ takes a single argument which is an array of values to aggregate. This is
220
+ especially useful to install new and/or override existing aggregation functions.
221
+ This also allows handling parameters:
222
+
223
+ Summaryse.register(:comma_join) do |ary|
224
+ ary.join(', ')
225
+ end
226
+ [1, 4, 12, 7].summaryse(:comma_join) # => "1, 4, 12, 7"
227
+
228
+ ## Aggregator objects
229
+
230
+ Sometimes it is useful to use your own objects as aggregators. For this, simply
231
+ provide them a to_summaryse function that returns an aggregation function:
232
+
233
+ class Foo
234
+ def to_summaryse; :sum; end
235
+ end
236
+ [1, 2, 3].summaryse(Foo.new).should eq(6)
237
+
238
+ Returned object is anything that can be seen as an aggregation function: a
239
+ Symbol, a Proc, a Hash, an Array, or even another such object:
240
+
241
+ class Bar
242
+ def to_summaryse; Foo.new; end
243
+ end
244
+ [1, 2, 3].summaryse(Bar.new).should eq(6)
245
+
246
+ ## Bypassing Hash entries
247
+
248
+ It is sometimes useful to explicit bypass specific Hash entries as the result of
249
+ the computation. Entries for which the aggregator returns Summaryse::BYPASS will
250
+ be simply removed from the result:
251
+
252
+ [
253
+ { :hobbies => [:ruby], :size => 12 },
254
+ { :hobbies => [:music], :size => 17 }
255
+ ].summaryse(:size => :max, :hobbies => lambda{|a| Summaryse::BYPASS})
256
+ # => {:size => "17"}
192
257
 
193
258
  # Contribute, Versioning and so on.
194
259
 
@@ -197,8 +262,14 @@ As usual: the code is on {http://github.com/blambeau/summaryse github}, I follow
197
262
  implementation details, that is, the method name, its recognized arguments and
198
263
  the semantics of the returned value), etc.
199
264
 
200
- Now, frankly, you can also copy/paste the source code of this simple array
201
- extension in your own project. This tend to be much friendly and much simpler
202
- than using a gem, IMHO. Reuse by copy-pasting even has a name:
203
- {http://revision-zero.org/reuse code scavenging}.
204
-
265
+ ## By the way, why this stupid name?
266
+
267
+ Just because summarize was already an {https://rubygems.org/gems/summarize existing gem}.
268
+ Summaryse is also much less likely to cause a name clash on the Array class. And
269
+ I'm a french-speaking developer :-)
270
+
271
+ And where does 'summarize' come from? The name is inspired by (yet not equivalent
272
+ to) {http://en.wikipedia.org/wiki/D_(data_language_specification)#Tutorial_D TUTORIAL D}'s
273
+ summarization operator on relations. See my {https://github.com/blambeau/alf alf}
274
+ project. Array#summaryse is rubyiesque in mind and does not conform to a purely
275
+ relational vision of summarization, though.
@@ -1,3 +1,48 @@
1
1
  require "summaryse/version"
2
2
  require "summaryse/loader"
3
+ module Summaryse
4
+
5
+ # Bypass marker
6
+ BYPASS = Object.new
7
+
8
+ #
9
+ # Registers a aggregation function under a given name.
10
+ #
11
+ # The lambda function is converted as a Proc from the supplied block.
12
+ # It takes one array argument, on which the aggregation must be done
13
+ # and returned.
14
+ #
15
+ # @param [Symbol] name a aggregation function name
16
+ # @param [lambda] the function itself
17
+ #
18
+ def self.register(name, &lambda)
19
+ @aggregators ||= {}
20
+ @aggregators[name] = lambda
21
+ end
22
+
23
+ #
24
+ # Returns an aggregator by name, nil if no such aggregator as been
25
+ # previously registered.
26
+ #
27
+ def self.aggregator(name)
28
+ @aggregators && @aggregators[name]
29
+ end
30
+
31
+ #
32
+ register(:count) {|a| a.size }
33
+ register(:sum) {|a| a.inject(:+) }
34
+ register(:avg) {|a| a.inject(:+)/a.size.to_f }
35
+
36
+ #
37
+ register(:first) {|a| a.first }
38
+ register(:last) {|a| a.last }
39
+ register(:min) {|a| a.min }
40
+ register(:max) {|a| a.max }
41
+
42
+ #
43
+ register(:intersection){|a| a.inject(:&) }
44
+ register(:union) {|a| a.inject(:|) }
45
+
46
+ end # module Summaryse
3
47
  require "summaryse/core_ext/array"
48
+
@@ -62,24 +62,22 @@ class Array
62
62
  case agg
63
63
  when Proc
64
64
  agg.call(self)
65
- when :avg
66
- inject(:+).to_f/size
67
- when :count
68
- size
69
- when :intersection
70
- inject(:&)
71
- when :sum
72
- inject(:+)
73
- when :union
74
- inject(:|)
75
65
  when Symbol
76
- self.send(agg)
66
+ if fn = Summaryse.aggregator(agg)
67
+ fn.call(self)
68
+ elsif self.respond_to?(agg)
69
+ self.send(agg)
70
+ else
71
+ raise ArgumentError, "No such aggregation function #{agg}"
72
+ end
77
73
  when Hash
78
74
  big = Hash.new{|h,k| h[k] = []}
75
+ agg.each_key{|k| big[k] = [] unless k.nil?}
79
76
  each{|t| t.each_pair{|k,v| big[k] << v}}
80
77
  Hash[big.collect{|k,v|
81
78
  if summ = (agg[k] || agg[nil])
82
- [k,v.summaryse(summ)]
79
+ res = v.summaryse(summ)
80
+ res == Summaryse::BYPASS ? nil : [k, res]
83
81
  end
84
82
  }.compact]
85
83
  when Array
@@ -91,8 +89,14 @@ class Array
91
89
  keys << key
92
90
  grouped[key] << t
93
91
  }
94
- agg = agg.merge(Hash[by.collect{|k| [k, :first]}])
92
+ agg = Hash[by.collect{|k| [k, :first]}].merge(agg)
95
93
  keys.uniq.collect{|key| grouped[key].summaryse(agg)}
94
+ else
95
+ if agg.respond_to?(:to_summaryse)
96
+ summaryse(agg.to_summaryse)
97
+ else
98
+ raise ArgumentError, "Unable to convert #{agg} to an aggregation function"
99
+ end
96
100
  end
97
101
  end
98
102
 
@@ -2,7 +2,7 @@ module Summaryse
2
2
  module Version
3
3
 
4
4
  MAJOR = 1
5
- MINOR = 0
5
+ MINOR = 1
6
6
  TINY = 0
7
7
 
8
8
  def self.to_s
@@ -58,6 +58,11 @@ describe "README file" do
58
58
  a.join(', ')
59
59
  }).should eq(:hobbies => [:ruby, :music], :size => "12, 17")
60
60
 
61
+ [
62
+ { :hobbies => [:ruby], :size => 12 },
63
+ { :hobbies => [:music], :size => 17 }
64
+ ].summaryse(:hello => lambda{|a| a}).should eq(:hello => [])
65
+
61
66
  [
62
67
  { :hobbies => {:day => [:ruby], :night => [:ruby] } },
63
68
  { :hobbies => {:day => [], :night => [:sleep]} }
@@ -109,4 +114,33 @@ describe "README file" do
109
114
  [ left, right ].summaryse(merge).should eq(exp)
110
115
  end
111
116
 
117
+ describe "Extra goodness" do
118
+
119
+ specify "On empty arrays" do
120
+ [].summaryse(:count).should eq(0)
121
+ [].summaryse(:first).should be_nil
122
+ [].summaryse(:intersection).should be_nil
123
+ [].summaryse(:last).should be_nil
124
+ [].summaryse(:min).should be_nil
125
+ [].summaryse(:sum).should be_nil
126
+ [].summaryse(:union).should be_nil
127
+ end
128
+
129
+ specify "Installing your own aggregators" do
130
+ Summaryse.register(:comma_join) do |ary|
131
+ ary.join(', ')
132
+ end
133
+ [1, 4, 12, 7].summaryse(:comma_join).should eq("1, 4, 12, 7")
134
+ end
135
+
136
+ specify "bypassing entries" do
137
+ agg = {:size => :max, :hobbies => lambda{|a| Summaryse::BYPASS}}
138
+ [
139
+ { :hobbies => [:ruby], :size => 12 },
140
+ { :hobbies => [:music], :size => 17 }
141
+ ].summaryse(agg).should eq({:size => 17})
142
+ end
143
+
144
+ end
145
+
112
146
  end
@@ -46,18 +46,27 @@ describe Summaryse do
46
46
  end
47
47
 
48
48
  it "should recognize max" do
49
+ [].summaryse(:max).should be_nil
49
50
  numbers.summaryse(:max).should eq(17)
50
51
  end
51
52
 
52
53
  it "should recognize sum" do
53
54
  numbers.summaryse(:sum).should eq(15 + 3 + 17 + 4 + 12)
54
- arrays.summaryse(:sum).should eq([ 15, 3, 12, 17, 4, 12])
55
+ arrays.summaryse(:sum).should eq([15, 3, 12, 17, 4, 12])
55
56
  end
56
57
 
57
58
  it "should recognize union" do
58
59
  arrays.summaryse(:union).should eq([15, 3, 12, 17, 4])
59
60
  end
60
61
 
62
+ it "should delegate to existing method otherwise" do
63
+ [1, 2, 2].summaryse(:uniq).should == [1, 2]
64
+ end
65
+
66
+ it "should raise when not found" do
67
+ lambda{ [1, 2, 2].summaryse(:no_such_one) }.should raise_error(ArgumentError)
68
+ end
69
+
61
70
  end # Symbol argument
62
71
 
63
72
  describe "when called with a Hash argument" do
@@ -87,6 +96,16 @@ describe Summaryse do
87
96
  rel.summaryse(control).should eq(:size => "hello")
88
97
  end
89
98
 
99
+ it "should allow specifying unexisting keys" do
100
+ control = {:no_such => lambda{|a| a}}
101
+ rel.summaryse(control).should eq(:no_such => [])
102
+ end
103
+
104
+ it "should allow specifying bypassed keys" do
105
+ control = {:size => :max, :hobbies => lambda{|a| Summaryse::BYPASS}}
106
+ rel.summaryse(control).should eq(:size => 12)
107
+ end
108
+
90
109
  end # Hash argument
91
110
 
92
111
  describe "when called with an Array argument" do
@@ -105,7 +124,30 @@ describe Summaryse do
105
124
  {:version => "2.0", :size => 99}
106
125
  ])
107
126
  end
127
+ end
128
+
129
+ describe "when called with a to_summarysable argument" do
130
+
131
+ it "should summarize as defined by the method" do
132
+ class Foo
133
+ def to_summaryse; :sum; end
134
+ end
135
+ [1, 2, 3].summaryse(Foo.new).should eq(6)
136
+
137
+ class Bar
138
+ def to_summaryse; Foo.new; end
139
+ end
140
+ [1, 2, 3].summaryse(Bar.new).should eq(6)
141
+ end
108
142
 
109
143
  end
144
+
145
+ describe "when called with something unconvertible" do
110
146
 
147
+ specify do
148
+ lambda{ [1,2,3].summaryse(Object.new).should raise_error(ArgumentError) }
149
+ end
150
+
151
+ end
152
+
111
153
  end
@@ -27,7 +27,7 @@ Gem::Specification.new do |s|
27
27
  #
28
28
  # The description should be more detailed than the summary. For example,
29
29
  # you might wish to copy the entire README into the description.
30
- s.description = "summaryse arrays with full power. Among others, this gem allows merging YAML\nconfiguration files,... "
30
+ s.description = "Summarize arrays with full power. As a side effect, this gem allows merging \nmultiple YAML configuration files with power, without sacrifying simplicity... "
31
31
 
32
32
  # The URL of this gem home page (optional)
33
33
  s.homepage = "http://github.com/blambeau/summaryse"
@@ -7,18 +7,19 @@ variables:
7
7
  lower:
8
8
  summaryse
9
9
  upper:
10
- summaryse
10
+ Summaryse
11
11
  version:
12
- 1.0.0
12
+ 1.1.0
13
13
  summary: |-
14
14
  Array#summaryse
15
15
  description: |-
16
- summaryse arrays with full power. Among others, this gem allows merging YAML
17
- configuration files,...
16
+ Summarize arrays with full power. As a side effect, this gem allows merging
17
+ multiple YAML configuration files with power, without sacrifying simplicity...
18
18
  authors:
19
19
  - { name: "Bernard Lambeau", email: blambeau@gmail.com }
20
20
  links:
21
21
  - http://github.com/blambeau/summaryse
22
+ - http://rubydoc.info/github/blambeau/summaryse/master/frames
22
23
  dependencies:
23
24
  - {name: rake, version: "~> 0.9.2", groups: [development]}
24
25
  - {name: bundler, version: "~> 1.0", groups: [development]}
metadata CHANGED
@@ -1,95 +1,130 @@
1
- --- !ruby/object:Gem::Specification
1
+ --- !ruby/object:Gem::Specification
2
2
  name: summaryse
3
- version: !ruby/object:Gem::Version
4
- version: 1.0.0
3
+ version: !ruby/object:Gem::Version
4
+ hash: 19
5
5
  prerelease:
6
+ segments:
7
+ - 1
8
+ - 1
9
+ - 0
10
+ version: 1.1.0
6
11
  platform: ruby
7
- authors:
12
+ authors:
8
13
  - Bernard Lambeau
9
14
  autorequire:
10
15
  bindir: bin
11
16
  cert_chain: []
12
- date: 2011-07-11 00:00:00.000000000Z
13
- dependencies:
14
- - !ruby/object:Gem::Dependency
15
- name: rake
16
- requirement: &74647200 !ruby/object:Gem::Requirement
17
+
18
+ date: 2011-07-12 00:00:00 Z
19
+ dependencies:
20
+ - !ruby/object:Gem::Dependency
21
+ version_requirements: &id001 !ruby/object:Gem::Requirement
17
22
  none: false
18
- requirements:
23
+ requirements:
19
24
  - - ~>
20
- - !ruby/object:Gem::Version
25
+ - !ruby/object:Gem::Version
26
+ hash: 63
27
+ segments:
28
+ - 0
29
+ - 9
30
+ - 2
21
31
  version: 0.9.2
22
32
  type: :development
33
+ requirement: *id001
23
34
  prerelease: false
24
- version_requirements: *74647200
25
- - !ruby/object:Gem::Dependency
26
- name: bundler
27
- requirement: &74646950 !ruby/object:Gem::Requirement
35
+ name: rake
36
+ - !ruby/object:Gem::Dependency
37
+ version_requirements: &id002 !ruby/object:Gem::Requirement
28
38
  none: false
29
- requirements:
39
+ requirements:
30
40
  - - ~>
31
- - !ruby/object:Gem::Version
32
- version: '1.0'
41
+ - !ruby/object:Gem::Version
42
+ hash: 15
43
+ segments:
44
+ - 1
45
+ - 0
46
+ version: "1.0"
33
47
  type: :development
48
+ requirement: *id002
34
49
  prerelease: false
35
- version_requirements: *74646950
36
- - !ruby/object:Gem::Dependency
37
- name: rspec
38
- requirement: &74646720 !ruby/object:Gem::Requirement
50
+ name: bundler
51
+ - !ruby/object:Gem::Dependency
52
+ version_requirements: &id003 !ruby/object:Gem::Requirement
39
53
  none: false
40
- requirements:
54
+ requirements:
41
55
  - - ~>
42
- - !ruby/object:Gem::Version
56
+ - !ruby/object:Gem::Version
57
+ hash: 31
58
+ segments:
59
+ - 2
60
+ - 4
61
+ - 0
43
62
  version: 2.4.0
44
63
  type: :development
64
+ requirement: *id003
45
65
  prerelease: false
46
- version_requirements: *74646720
47
- - !ruby/object:Gem::Dependency
48
- name: yard
49
- requirement: &74646490 !ruby/object:Gem::Requirement
66
+ name: rspec
67
+ - !ruby/object:Gem::Dependency
68
+ version_requirements: &id004 !ruby/object:Gem::Requirement
50
69
  none: false
51
- requirements:
70
+ requirements:
52
71
  - - ~>
53
- - !ruby/object:Gem::Version
72
+ - !ruby/object:Gem::Version
73
+ hash: 7
74
+ segments:
75
+ - 0
76
+ - 7
77
+ - 2
54
78
  version: 0.7.2
55
79
  type: :development
80
+ requirement: *id004
56
81
  prerelease: false
57
- version_requirements: *74646490
58
- - !ruby/object:Gem::Dependency
59
- name: bluecloth
60
- requirement: &74646260 !ruby/object:Gem::Requirement
82
+ name: yard
83
+ - !ruby/object:Gem::Dependency
84
+ version_requirements: &id005 !ruby/object:Gem::Requirement
61
85
  none: false
62
- requirements:
86
+ requirements:
63
87
  - - ~>
64
- - !ruby/object:Gem::Version
88
+ - !ruby/object:Gem::Version
89
+ hash: 29
90
+ segments:
91
+ - 2
92
+ - 0
93
+ - 9
65
94
  version: 2.0.9
66
95
  type: :development
96
+ requirement: *id005
67
97
  prerelease: false
68
- version_requirements: *74646260
69
- - !ruby/object:Gem::Dependency
70
- name: wlang
71
- requirement: &74646030 !ruby/object:Gem::Requirement
98
+ name: bluecloth
99
+ - !ruby/object:Gem::Dependency
100
+ version_requirements: &id006 !ruby/object:Gem::Requirement
72
101
  none: false
73
- requirements:
102
+ requirements:
74
103
  - - ~>
75
- - !ruby/object:Gem::Version
104
+ - !ruby/object:Gem::Version
105
+ hash: 53
106
+ segments:
107
+ - 0
108
+ - 10
109
+ - 1
76
110
  version: 0.10.1
77
111
  type: :development
112
+ requirement: *id006
78
113
  prerelease: false
79
- version_requirements: *74646030
80
- description: ! 'summaryse arrays with full power. Among others, this gem allows merging
81
- YAML
82
-
83
- configuration files,... '
84
- email:
114
+ name: wlang
115
+ description: "Summarize arrays with full power. As a side effect, this gem allows merging \n\
116
+ multiple YAML configuration files with power, without sacrifying simplicity... "
117
+ email:
85
118
  - blambeau@gmail.com
86
119
  executables: []
120
+
87
121
  extensions: []
88
- extra_rdoc_files:
122
+
123
+ extra_rdoc_files:
89
124
  - README.md
90
125
  - CHANGELOG.md
91
126
  - LICENCE.md
92
- files:
127
+ files:
93
128
  - summaryse.gemspec
94
129
  - summaryse.noespec
95
130
  - CHANGELOG.md
@@ -115,35 +150,38 @@ files:
115
150
  - tasks/debug_mail.txt
116
151
  homepage: http://github.com/blambeau/summaryse
117
152
  licenses: []
153
+
118
154
  post_install_message:
119
155
  rdoc_options: []
120
- require_paths:
156
+
157
+ require_paths:
121
158
  - lib
122
- required_ruby_version: !ruby/object:Gem::Requirement
159
+ required_ruby_version: !ruby/object:Gem::Requirement
123
160
  none: false
124
- requirements:
125
- - - ! '>='
126
- - !ruby/object:Gem::Version
127
- version: '0'
128
- segments:
161
+ requirements:
162
+ - - ">="
163
+ - !ruby/object:Gem::Version
164
+ hash: 3
165
+ segments:
129
166
  - 0
130
- hash: 872999347
131
- required_rubygems_version: !ruby/object:Gem::Requirement
167
+ version: "0"
168
+ required_rubygems_version: !ruby/object:Gem::Requirement
132
169
  none: false
133
- requirements:
134
- - - ! '>='
135
- - !ruby/object:Gem::Version
136
- version: '0'
137
- segments:
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ hash: 3
174
+ segments:
138
175
  - 0
139
- hash: 872999347
176
+ version: "0"
140
177
  requirements: []
178
+
141
179
  rubyforge_project:
142
180
  rubygems_version: 1.8.5
143
181
  signing_key:
144
182
  specification_version: 3
145
183
  summary: Array#summaryse
146
- test_files:
184
+ test_files:
147
185
  - spec/spec_helper.rb
148
186
  - spec/readme_spec.rb
149
187
  - spec/summaryse_spec.rb