facets 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
data/AUTHORS CHANGED
@@ -49,6 +49,7 @@ work is greatly appreciated.
49
49
  * Tim Pease
50
50
  * Jonas Pfenniger
51
51
  * Ryan Platte
52
+ * Oliver Renaud
52
53
  * Christoph Rippel
53
54
  * Daniel Schierbeck
54
55
  * Gavin Sinclair
@@ -57,6 +58,7 @@ work is greatly appreciated.
57
58
  * Peter Vanbroekhoven
58
59
  * Jim Weirich
59
60
  * Jeff Wood
61
+ * Erik Veenstra
60
62
  * Austin Ziegler
61
63
  * Why The Lucky Stiff
62
64
 
data/README CHANGED
@@ -7,68 +7,54 @@
7
7
 
8
8
  == Introduction
9
9
 
10
- Ruby Facets is the singele largest collection of general purpose method extensions
11
- and system additions for the Ruby programming language.
10
+ Ruby Facets is the single largest collection of general purpose method extensions and system additions for the Ruby programming language.
12
11
 
13
- The core extensions is a large collection of methods which extend the core capabilities of Ruby's
14
- built-in classes and modules. This collection of extension methods are unique by virtue of
15
- their atomicity. The methods are stored in relatively small groups of tightly coupled methods so
16
- that each can be required independently. This gives developers the potential for much finer
17
- control over which extra methods to bring into their code.
12
+ The core extensions is a large collection of methods which extend the core capabilities of Ruby's built-in classes and modules. This collection of extension methods are unique by virtue of their atomicity. The methods are stored in relatively small groups of tightly coupled methods so that each can be required independently. This gives developers the potential for much finer control over which extra methods to bring into their code.
18
13
 
19
- The "more" additions are a collection of classes, modules and light meta-systems which
20
- consitutes an ever improving source of reusable components. Some very nice additions are
21
- provided, from the simple Functor class to a full-blown annotations system.
14
+ The "more" additions are a collection of classes, modules and light meta-systems which constitutes an ever improving source of reusable components. Some very nice additions are provided, from the simple Functor class to a full-blown annotations system.
22
15
 
23
16
 
24
17
  == Installation
25
18
 
26
- Ycan intall either via RubyGems or manually:
19
+ The easiest way to install is via RubyGems.
27
20
 
28
- % gem install facets
21
+ $ gem install facets
29
22
 
30
- or
23
+ To install manually, download and unpack the .tar.gz package and use the included
24
+ task/install script. Eg.
31
25
 
32
- % tar -xzf facets-2.x.x.tar.gz
33
- % cd facets-2.x.x
34
- % sudo task/setup
26
+ $ tar -xvzf facets-2.x.x.tar.gz
27
+ $ cd facets-2.x.x
28
+ $ sudo task/setup
35
29
 
30
+ On Window the last step will be:
36
31
 
37
- == Compatability with 1.x series.
32
+ C:\> ruby task/setup
38
33
 
39
- Prior to 2.0, Facets was divided between CORE and MORE --standalone extensions vs.
40
- classes and modules, respectively. With 2.0, the idea of CORE has take only a
41
- slightly new meaning. Instead CORE now represents the libraries that are considerd essential
42
- and as such are loaded automatically when using ++require "facets"++. While still primarily
43
- made up of extension methods a few classes now belong to core as well. In conjuction
44
- with this the extension methods are no longer stored on a per-method basis, but rather in
45
- tight knit packs. While dividing the extension methods up on a per-method basis had certain advantages,
46
- not the least of which was a simple organization, it proved too granular --rather than "atomic"
47
- it was "subatomic". With 2.0 we have address this issue. All the extension methods have now been
48
- orgnized into small tightly related groups.
34
+ IMPORTANT! Note that setup.rb is no longer used b/c of Facets' new layout.
49
35
 
50
- However, being able to require on the basis of a method is still a useful approach,
51
- so a compatability layer for the 1.x series has been created. It makes it possible to
52
- load Facets libraries on a per method basis, just as before, via require redirection.
53
36
 
54
- For example:
37
+ == Compatibility with 1.x series.
38
+
39
+ Prior to 2.0, Facets was divided between CORE and MORE --standalone extensions vs. classes and modules, respectively. With 2.0, the notion of "CORE" has taken only a slightly differnt meaning. Instead CORE now consists of the libraries that are thought essential and as such are loaded automatically when using ++require "facets"++. While still primarily made up of extension methods a few classes now belong to core as well.
40
+
41
+ Additionally, the extension methods are no longer stored on a per-method basis. While dividing the extension methods up on a per-method basis had certain advantages, not the least of which was a simple organization, it proved too granular --more "subatomic" than "atomic". With 2.0 we have address this issue. All the extension methods have now been organized into small tightly related groups.
42
+ However, being able to require on the basis of a method is still a useful approach, so a compatibility layer for the 1.x series has been created. It makes it possible to load Facets libraries on a per method basis, just as before, via require redirection. For example:
55
43
 
56
- require 'facets/core/string/underscore'
44
+ require 'facets/string/underscore'
57
45
 
58
- Will redirect according to the content of the underscore.rb file:
46
+ Will redirect according to the content of the underscore.rb file which is:
59
47
 
60
48
  require 'facets/string/stylize'
61
49
 
62
- So the underscore method will be loaded just as before. But a few other *stylization*
63
- methods will be loaded as well. This actually proves a more useful approach b/c
64
- often one will want to use one of the related methods as well.
50
+ So the underscore method will be loaded just as before. But a few other *stylization* methods will also be loaded. This actually proves a more useful approach because quite often a related method is needed as well.
51
+
52
+ The other significant change from 1.x to 2.0 is the removal of some libraries that were considered too extraneous for a general purpose library. Most of these were spun-off to their own projects. In particular, the web-related libs are now part of Blow (http://blow.rubyforge.org), inflection libraries are in English (http://english.rubyforge.org), units.rb along with constants.rb are in Stick (http://stick.rubyforge.org), and the persistance system in Opod (http://opod.rubyforge.org).
65
53
 
66
54
 
67
55
  == Mission
68
56
 
69
- Facets holds to the notion that the more we can reasonably integrate into
70
- a common foundation directed toward general needs, the better that foundation
71
- will be able to serve everyone. There are a number of advantages here:
57
+ Facets holds to the notion that the more we can reasonably integrate into a common foundation directed toward general needs, the better that foundation will be able to serve everyone. There are a number of advantages here:
72
58
 
73
59
  * Better Code-reuse
74
60
  * Collaborative Improvements
@@ -78,43 +64,24 @@ will be able to serve everyone. There are a number of advantages here:
78
64
 
79
65
  == Status
80
66
 
81
- The current status is quite good. While some parts are still considered
82
- beta, everything is relatively usable.
83
-
67
+ The current status of Facets is very good. While some libs could still use some "finishing" work, all are highly API stable and functional.
84
68
 
85
- == Installation
86
-
87
- The easiest way to install is via RubyGems. On the command line enter:
88
-
89
- > gem install facets
90
-
91
- To manually install, unpack the .tar.bz2 package and use the included
92
- setup.rb script. For example:
93
-
94
- > tar -xvzf facets-x.x.x.tar.gz
95
- > cd facets-x.x.x
96
- > sudo util/setup
97
-
98
- On Window the last step will be:
99
69
 
100
- > ruby util/setup
70
+ == Usage
101
71
 
72
+ For detailed usage of any given method or module please refer to the API RDocs.
102
73
 
103
- == Usage
74
+ http://facets.rubyforge.org/learn.html
104
75
 
105
- For detailed usage of any given method or module please refer to the
106
- API RDocs. Most are well documented. Assistance in improving
107
- documentation though is always appreciated.
76
+ Most libraries are well documented. Assistance in improving documentation though is always appreciated.
108
77
 
109
- If you plan to use more then a few of Facets core method it is recommended
110
- that you require require the main facility.
78
+ If you plan to use more then a few of Facets core method it is recommended that you require require the main facility.
111
79
 
112
80
  require 'facets'
113
81
 
114
82
  This loads all the CORE functionality at once.
115
83
 
116
- Of course you can use the CORE library piecemenal if you prefer.
117
- The general require statement for a core extensions library is:
84
+ Of course you can use the CORE library piecemeal if you prefer. The general require statement for a core extensions library is:
118
85
 
119
86
  require 'facets/<class|module>/<method-lib>'
120
87
 
@@ -122,48 +89,38 @@ For example:
122
89
 
123
90
  require 'facets/time/stamp'
124
91
 
125
- Most "atoms" contain only a few methods, sometimes only one, but a few excpetions
126
- provide quite a few method, such as ++string/indexable.rb++.
92
+ Most "atoms" contain only a few methods, sometimes only one, but a few exceptions provide quite a few method, such as ++string/indexable.rb++.
127
93
 
128
- You can load per-class or per-module groups of core methods by requiring the class
129
- or module by name. For example"
94
+ You can load per-class or per-module groups of core methods by requiring the class or module by name. For example"
130
95
 
131
96
  require 'facets/time'
132
97
 
133
98
  Will require all the Time method extensions.
134
99
 
135
- Note that some methods that were part of CORE in 1.8 and earlier are now
136
- part of MORE libraries. A good example is 'random.rb'. There were separated
137
- b/c they had more specialized usecases, where as CORE extensions are
138
- intended as general purpose.
100
+ Note that some methods that were part of CORE in 1.8 and earlier are now part of MORE libraries. A good example is 'random.rb'. There were separated b/c they had more specialized usecases, where as CORE extensions are intended as general purpose.
139
101
 
140
- Using a Facets/MORE library of modules, classes or microframeworks
141
- is essentially the same. For example:
102
+ Using a Facets/MORE library of modules, classes or microframeworks is essentially the same. For example:
142
103
 
143
104
  require 'facets/basicobject'
144
105
 
106
+ Again, for details pertaining to the functionality of each feature, please see the API Docs.
107
+
108
+
145
109
  # PLEASE IGNORE THIS FOR NOW
146
- #
147
- # It is possible to eliminate the need for the 'facets/' prefix on requires if
148
- # the Facets libpaths are added to the LOAD_PATH. But this isn't as straight-foward
149
- # as it is for most libraries b/c of the layout of Facets library.
150
- #
151
- # require 'facets-topload'
152
- # require 'basicobject'
153
- #
154
- # Understand that on the off chance that another library has the same name as
155
- # one of Facets' everything will still work fine. You will just not be able to use the
156
- # prefixless shorcut to require it.
157
- #
158
- # END.
159
110
 
160
- Again, for details pertaining to the functionality of each feature, please see the API Docs.
111
+ It is possible to eliminate the need for the 'facets/' prefix on requires if the Facets libpaths are added to the LOAD_PATH. But this isn't as straight-forward as it is for most libraries b/c of the layout of Facets library.
112
+
113
+ require 'facets-topload'
114
+ require 'basicobject'
115
+
116
+ Understand that on the off chance that another library has the same name as one of Facets' everything will still work fine. You will just not be able to use the prefixless shortcut to require it.
117
+
118
+ # END IGNORE.
161
119
 
162
120
 
163
121
  == Method File Names
164
122
 
165
- Operator method redirect files are stored using english names. For instance for
166
- Proc#* is 'proc/op_mul'.
123
+ Operator method redirect files are stored using English names. For instance for Proc#* is 'proc/op_mul'.
167
124
 
168
125
  For reference, here is the chart.
169
126
 
@@ -192,43 +149,29 @@ For reference, here is the chart.
192
149
  []= => op_store
193
150
  [] => op_fetch
194
151
 
195
- Facets simply takes the '*' and translates it into a string acceptable
196
- to all file systems. Also, if a method ends in '=', '?' or '!' it is
197
- simply removed.
152
+ Facets simply takes the '*' and translates it into a string acceptable to all file systems. Also, if a method ends in '=', '?' or '!' it is simply removed.
198
153
 
199
154
 
200
155
  == Contribute
201
156
 
202
157
  This project thrives on contribution.
203
158
 
204
- If you have any extension methods, classes, modules or small frameworks
205
- that you think have general applicability and would like to see them
206
- included in this project, don't hesitiate to submit. There's a very good
207
- chance it will be included. Also, if you have better versions of any thing
208
- already included or simply have a patch, they too are more than welcome.
209
- We want Ruby Facets to be of the highest quality.
159
+ If you have any extension methods, classes, modules or small frameworks that you think have general applicability and would like to see them included in this project, don't hesitiate to submit. There's a very good chance it will be included. Also, if you have better versions of any thing already included or simply have a patch, they too are more than welcome. We want Ruby Facets to be of the highest quality.
210
160
 
211
161
 
212
162
  == Authors
213
163
 
214
- This collection was put together by, and largely written by Thomas Sawyer
215
- (aka Trans). He can be reached via email at transfire at gmail.com.
164
+ This collection was put together by, and largely written by Thomas Sawyer (aka Trans). He can be reached via email at transfire at gmail.com.
216
165
 
217
- Some parts of this collection were written and/or inspired by other
218
- persons. Fortunately nearly all were copyrighted under the same open
219
- license, the Ruby License. In the few excpetions I have included the
220
- copyright notice with the source code.
166
+ Some parts of this collection were written and/or inspired by other persons. Fortunately nearly all were copyrighted under the same open license, the Ruby License. In the few exceptions I have included the copyright notice with the source code.
221
167
 
222
- Any code file not specifically labelled shall fall under the Ruby License.
168
+ Any code file not specifically labeled shall fall under the Ruby License.
223
169
 
224
- In all cases, I have made every effort to give credit where credit is due.
225
- You will find these copyrights, thanks and acknowledgements embedded in the
226
- source code, and an unobtrusive "Author(s)" section is given in the RDocs.
170
+ In all cases, I have made every effort to give credit where credit is due. You will find these copyrights, thanks and acknowledgments embedded in the source code, and an unobtrusive "Author(s)" section is given in the RDocs.
227
171
 
228
172
  Also see the AUTHORS file for a list of all contributing Rubyists.
229
173
 
230
- If anyone is missing from the list, please let me know and
231
- I will correct right away. Thanks.
174
+ If anyone is missing from the list, please let me know and I will correct right away. Thanks.
232
175
 
233
176
 
234
177
  == License
@@ -240,27 +183,9 @@ The collection PER COLLECTION is licensed as follows:
240
183
 
241
184
  Distributed under the terms of the Ruby license.
242
185
 
243
- The Ruby license is a dual license that also provides for use of the GPL.
244
- Complete texts of both licenses accompany this document (see doc/COPYING).
245
-
246
- This program is free software; you can redistribute it and/or modify
247
- it under the terms of the GNU General Public License as published by
248
- the Free Software Foundation; either version 2 of the License, or
249
- (at your option) any later version.
250
-
251
- This program is distributed in the hope that it will be useful,
252
- but WITHOUT ANY WARRANTY; without even the implied warranty of
253
- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
254
- GNU General Public License for more details.
255
-
256
- You should have received a copy of the GNU General Public License
257
- along with this program; if not, write to the Free Software
258
- Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
186
+ The Ruby license is a dual license that also provides for use of the GPL. Complete texts of both licenses accompany this document (see LICENSE).
259
187
 
260
- Acknowledgments and Copyrights for particular snippets of borrowed code
261
- are given in their respective source. All licenses are either compatible
262
- with the Ruby license (namely the GPL) or the original author has given
263
- permission for inclusion of their code under such lincense.
188
+ Acknowledgments and Copyrights for particular snippets of borrowed code are given in their respective source. All licenses are either compatible with the Ruby license (namely the GPL) or the original author has given permission for inclusion of their code under such license.
264
189
 
265
190
 
266
191
  == Pitch
@@ -270,14 +195,7 @@ permission for inclusion of their code under such lincense.
270
195
 
271
196
  ----
272
197
 
273
- [1] A lot of mental anguish went into finding this good project name Ruby Facets.
274
- Of course, in the end only one name can take the honor. Other good names
275
- which were considered: Calibre, Florida and California, Warchest w/ Atomix,
276
- Downs & Ace, Trix & Atomx and even Pillbox & Pills (a _why suggestion).
277
- Then the names that almost won out and were used for a good while:
278
- Nano Methods and Mega Modules --great names but a little to "fad".
279
- Finally let's not forget even older "working" titles that were used
280
- along the way: Raspberry, ABC, Succ and the very original Tomslib.
198
+ [1] A lot of mental anguish went into finding this good project name Ruby Facets. Of course, in the end only one name can take the honor. Other good names which were considered: Calibre, Florida and California, Warchest w/ Atomix, Downs & Ace, Trix & Atomx and even Pillbox & Pills (a _why suggestion). Then the names that almost won out and were used for a good while: Nano Methods and Mega Modules --great names but a little to "fad". Finally let's not forget even older "working" titles that were used along the way: Raspberry, ABC, Succ and the very original Tomslib.
281
199
 
282
200
  ----
283
201
 
@@ -0,0 +1,84 @@
1
+ require 'benchmark'
2
+
3
+ module Enumerable
4
+
5
+ # group_by
6
+
7
+ def group_by_1(&block)
8
+ h = k = e = nil
9
+ r = Hash.new
10
+ each{|e| (r[yield(e)] ||= []) << e}
11
+ r
12
+ end
13
+
14
+ def group_by_2(&block)
15
+ r = Hash.new{ |h,k| h[k]=[] }
16
+ each{|e| r[yield(e)] << e}
17
+ r
18
+ end
19
+
20
+ # cluster_by
21
+
22
+ def cluster_by_1(&block)
23
+ group_by_1(&block).values # No sorting.
24
+ end
25
+
26
+ def cluster_by_2(&block)
27
+ #partition_by_fast(&block).values.sort # Sorted by value.
28
+ group_by_1(&block).sort.transpose.pop # Sorted by key.
29
+ end
30
+
31
+ def cluster_by_3(&block) # As defined by Facets.
32
+ h = {}
33
+ each{|e| (h[block[e]] ||= []) << e}
34
+ h.keys.sort!.map{|k| h[k]} # Sorted by key.
35
+ end
36
+
37
+ end
38
+
39
+ #
40
+
41
+ Benchmark.bmbm do |x|
42
+ n = 10
43
+ a = (0...10000).to_a + (0...10000).to_a
44
+ h = (0...10000).inject({}){|h, e| h[e] = e ; h}
45
+
46
+ # group_by
47
+
48
+ x.report("group_by_1") do
49
+ n.times do
50
+ a.group_by_1{|e| e % 10}
51
+ h.group_by_1{|k, v| v % 10}
52
+ end
53
+ end
54
+
55
+ x.report("group_by_2") do
56
+ n.times do
57
+ a.group_by_2{|e| e % 10}
58
+ h.group_by_2{|k, v| v % 10}
59
+ end
60
+ end
61
+
62
+ # cluster_by
63
+
64
+ x.report("cluster_by_1") do
65
+ n.times do
66
+ a.cluster_by_1{|e| e % 10}
67
+ h.cluster_by_1{|k, v| v % 10}
68
+ end
69
+ end
70
+
71
+ x.report("cluster_by_2") do
72
+ n.times do
73
+ a.cluster_by_2{|e| e % 10}
74
+ h.cluster_by_2{|k, v| v % 10}
75
+ end
76
+ end
77
+
78
+ x.report("cluster_by_3") do
79
+ n.times do
80
+ a.cluster_by_3{|e| e % 10}
81
+ h.cluster_by_3{|k, v| v % 10}
82
+ end
83
+ end
84
+ end
@@ -0,0 +1,58 @@
1
+ require 'benchmark'
2
+
3
+ module Enumerable
4
+
5
+ # duplicates
6
+
7
+ def duplicates_1
8
+ h1 = {}
9
+ h2 = {}
10
+ each {|i|
11
+ h2[i] = true if h1[i]
12
+ h1[i] = true
13
+ }
14
+ h2.keys
15
+ end
16
+
17
+ def duplicates_2
18
+ inject(Hash.new(0)){|h,v| h[v]+=1; h}.reject{|k,v| v==1}.keys
19
+ end
20
+
21
+ # uniq_by
22
+
23
+ def uniq_by_1 #:yield:
24
+ h = {}; inject([]) {|a,x| h[yield(x)] ||= a << x}
25
+ end
26
+
27
+ def uniq_by_2
28
+ inject({}) { |h,x| h[yield(x)] ||= x; h }.values
29
+ end
30
+
31
+ end
32
+
33
+ #
34
+
35
+ Benchmark.bmbm do |x|
36
+ n = 10000
37
+ a = [1,1,2,3,4,4,5,6,7,7]
38
+
39
+ # duplicates
40
+
41
+ x.report("duplicates_1") do
42
+ n.times { a.duplicates_1 }
43
+ end
44
+
45
+ x.report("duplicates_2") do
46
+ n.times { a.duplicates_2 }
47
+ end
48
+
49
+ # uniq_by
50
+
51
+ x.report("uniq_by_1") do
52
+ n.times { a.uniq_by_1{ |x| x } }
53
+ end
54
+
55
+ x.report("uniq_by_2") do
56
+ n.times { a.uniq_by_2{ |x| x } }
57
+ end
58
+ end