facets 2.8.2 → 2.8.3

Sign up to get free protection for your applications and to get access to all the features.
Files changed (57) hide show
  1. data/AUTHORS +13 -11
  2. data/HISTORY.rdoc +58 -0
  3. data/lib/core/facets/array/recursive.rb +91 -0
  4. data/lib/core/facets/array/recursively.rb +2 -2
  5. data/lib/core/facets/array/traverse.rb +23 -6
  6. data/lib/core/facets/enumerable/collisions.rb +1 -0
  7. data/lib/core/facets/enumerable/commonality.rb +4 -2
  8. data/lib/core/facets/enumerable/graph.rb +37 -1
  9. data/lib/core/facets/enumerable/mash.rb +1 -39
  10. data/lib/core/facets/enumerable/recursive.rb +75 -0
  11. data/lib/core/facets/enumerable/visit.rb +30 -0
  12. data/lib/core/facets/file/ext.rb +36 -0
  13. data/lib/core/facets/hash/graph.rb +18 -0
  14. data/lib/core/facets/hash/mash.rb +1 -18
  15. data/lib/core/facets/hash/recursive.rb +180 -0
  16. data/lib/core/facets/hash/recursive_merge.rb +6 -0
  17. data/lib/core/facets/hash/recursively.rb +2 -2
  18. data/lib/core/facets/hash/to_module.rb +26 -0
  19. data/lib/core/facets/hash/to_proc.rb +2 -2
  20. data/lib/core/facets/hash/traverse.rb +19 -13
  21. data/lib/core/facets/kernel/assign.rb +63 -0
  22. data/lib/core/facets/kernel/assign_from.rb +45 -0
  23. data/lib/core/facets/kernel/dup.rb +63 -0
  24. data/lib/core/facets/kernel/instance.rb +156 -0
  25. data/lib/core/facets/kernel/instance_assign.rb +1 -22
  26. data/lib/core/facets/kernel/meta_def.rb +4 -0
  27. data/lib/core/facets/kernel/populate.rb +1 -74
  28. data/lib/core/facets/kernel/set_from.rb +2 -0
  29. data/lib/core/facets/kernel/try_dup.rb +1 -0
  30. data/lib/core/facets/module/set.rb +36 -0
  31. data/lib/core/facets/objectspace/reflect.rb +45 -0
  32. data/lib/core/facets/struct/attributes.rb +6 -2
  33. data/lib/core/facets/symbol/op_div.rb +19 -0
  34. data/lib/core/facets/to_hash.rb +12 -0
  35. data/lib/more/facets/casting_hash.rb +172 -0
  36. data/lib/more/facets/pathname.rb +36 -0
  37. data/lib/more/facets/prepend.rb +57 -0
  38. data/lib/more/facets/random.rb +19 -3
  39. data/lib/more/facets/roman.rb +46 -153
  40. data/lib/more/facets/stash.rb +148 -33
  41. data/meta/released +1 -1
  42. data/meta/version +1 -1
  43. data/test/core/array/test_recursive.rb +18 -0
  44. data/test/core/enumerable/test_recursive.rb +18 -0
  45. data/test/core/file/test_ext.rb +31 -0
  46. data/test/core/hash/test_recursive.rb +23 -0
  47. data/test/core/hash/test_to_module.rb +21 -0
  48. data/test/core/kernel/test_assign.rb +57 -0
  49. data/test/core/kernel/test_assign_from.rb +20 -0
  50. data/test/more/test_prepend.rb +28 -0
  51. data/test/more/test_random.rb +40 -4
  52. metadata +39 -10
  53. data/lib/core/facets/kernel/instance_variables.rb +0 -97
  54. data/lib/more/facets/instance_eval.rb +0 -50
  55. data/lib/more/facets/ioredirect.rb +0 -77
  56. data/lib/more/facets/plugin_manager.rb +0 -50
  57. data/test/core/kernel/test_populate.rb +0 -46
data/AUTHORS CHANGED
@@ -9,17 +9,19 @@
9
9
  The following developers have recently contributed to the development of Facets.
10
10
  They are held in the highest regard for their efforts.
11
11
 
12
- * Roger Pack Added generational depth to Class#descendants.
13
- * Marco Otte-Witte Fixed return value of Kernel#extend.
14
- * Mauro Tortonesi Fixed issues with duration.rb and date.rb.
15
- * Sandor Szücs Fixes for String#align_right and #align_left.
16
- * Tyler Rick Fixed bug in Time#hence and #ago.
17
- * Brian Candler Provided Enumerator::Filter.
18
- * Jeena Paradies Provided INI implementation.
19
- * Robert Klemme Fix for Enumerable#mode.
20
- * Daniel Schierbeck Speed imporvements to odd? and even?
21
- * Ken Bloom For DictionaryMatcher class (class might be renamed in future).
22
- * Matthew Harris Incorporated very useful Duration class.
12
+ * Lavir the Whiolet Improved Range#at_rand and added File#ext.
13
+ * Jean-Denis Vauguet Added Pathname#visit.
14
+ * Roger Pack Added generational depth to Class#descendants.
15
+ * Marco Otte-Witte Fixed return value of Kernel#extend.
16
+ * Mauro Tortonesi Fixed issues with duration.rb and date.rb.
17
+ * Sandor Szücs Fixes for String#align_right and #align_left.
18
+ * Tyler Rick Fixed bug in Time#hence and #ago.
19
+ * Brian Candler Provided Enumerator::Filter.
20
+ * Jeena Paradies Provided INI implementation.
21
+ * Robert Klemme Fix for Enumerable#mode.
22
+ * Daniel Schierbeck Speed imporvements to odd? and even?
23
+ * Ken Bloom For DictionaryMatcher class (class might be renamed in future).
24
+ * Matthew Harris Incorporated very useful Duration class.
23
25
 
24
26
  == Recent Bug Reports
25
27
 
@@ -1,5 +1,63 @@
1
1
  = Facets Release History
2
2
 
3
+ == 2.8.3 / 2009-04-10
4
+
5
+ New release which makes a few adjustments in Kernel core extensions,
6
+ adds a few new extensions and additions, plus other small improvements.
7
+ The biggest change is the addition of Recusor, which is created via
8
+ Enumerable#recursive. This class is somewhat like Enumerator and
9
+ provides a number of recursive methods.
10
+
11
+ Changes:
12
+
13
+ * 9 New Core Extensions
14
+
15
+ * Enumerable#recursive provides a number of other recursive methods.
16
+ * Enumerable#visit can be used to recursively iterate any Enumerable.
17
+ * Module#set has been added (from Sinatra).
18
+ * Symbol#/ is added to be like String#/.
19
+ * Struct#to_h is added and will ultimately replace Struct#attributes.
20
+ * ObjectSpace#reflect routes method calls to Kernel context.
21
+ * Hash#to_module converts a hash to mixin module (Jay Fields).
22
+ * Kernel#dup! is same as #try_dup from extlib.
23
+ * Add File#ext which is a useful variation of #extname (Lavir the Whiolet).
24
+
25
+ * 3 Core Extensions Renamed
26
+
27
+ * renamed #set_from to #assign_from (alias remains until Kernel#set is considerd).
28
+ * rename #populate to #assign and improve.
29
+ * Kernel#instance_vars is now Kernel#instance and also more useful.
30
+
31
+ * 1 Core Deprecation
32
+
33
+ * Removed #instance_eval hack.
34
+
35
+ * 2 Core Bug Fixes
36
+
37
+ * #map_with_index now uses #each_with_index.
38
+ * #to_proc_with_response spelling correction.
39
+
40
+ * 1 Core Adjustment
41
+
42
+ * Aliased #metadef to #meta_def.
43
+
44
+ * 3 New More Libraries
45
+
46
+ * casting_hash.rb provides CastingHash class, a hash with flexible keys and values.
47
+ * prepend.rb allows for AOP-like inclusion of modules.
48
+ * roman.rb provides simple roman numeral extensions to String and Integer.
49
+
50
+ * 5 More Improvements
51
+
52
+ * Pathname#visit for iterating all entries beneath a path (chikamichi).
53
+ * Pathname#to_str, b/c Pathname is basically a type of String (from extlib).
54
+ * Range#at_rand in random.rb handles Float ranges (Lavir the Whiolet).
55
+ * FileUtils#cp_rx provides controlled copies.
56
+ * Stash class in stash.rb is improved and is now available as a stand-alone library.
57
+ * ioredirect.rb has been removed as IORedirect no longer worked.
58
+ * plugin_manager.rb has been removed. Use 'plugin' gem instead.
59
+
60
+
3
61
  == 2.8.2 / 2009-02-22
4
62
 
5
63
  This release fixes a bug by removing Numeric#size. Turns out that was a
@@ -0,0 +1,91 @@
1
+ require 'facets/enumerable/recursive'
2
+
3
+ class Array
4
+
5
+ # Apply a block to array, and recursively apply that block
6
+ # to each subarray.
7
+ #
8
+ # arr = ["a", ["b", "c", nil], nil]
9
+ # arr.recursively{|a| a.compact! }
10
+ # => ["a", ["b", "c"]]
11
+ #
12
+ def recursive(opts={}, &block)
13
+ if block
14
+ a = inject([]) do |array, value|
15
+ if value.is_a?(Array)
16
+ array << value.recursive(&block)
17
+ else
18
+ array << value
19
+ end
20
+ array
21
+ end
22
+ yield a
23
+ else
24
+ Recursor.new(self, opts)
25
+ end
26
+ end
27
+
28
+ # In place form of #recursive.
29
+
30
+ def recursive!(&block)
31
+ r = recursive(&block)
32
+ raise TypeError unless Array === r
33
+ replace(r)
34
+ end
35
+
36
+
37
+ #
38
+ class Recursor < ::Enumerable::Recursor
39
+
40
+ # Recursively iterate over the Array's elements.
41
+ # If an element is an Array or responds to #to_ary
42
+ # then it will be itereated over as well.
43
+ #
44
+ def each(&block)
45
+ if block_given?
46
+ @enum.each do |e|
47
+ if Array === e || e.respond_to?(:to_ary)
48
+ e.to_ary.recursive.each(&block)
49
+ else
50
+ block.call(e)
51
+ end
52
+ end
53
+ else
54
+ to_enum(:each)
55
+ end
56
+ end
57
+
58
+ # Returns a new array created by traversing the array and its
59
+ # sub-arrays, executing the given block on the elements.
60
+ #
61
+ # h = ["A", "B", ["X", "Y"]]
62
+ #
63
+ # g = h.recursive.map{ |e| e.downcase }
64
+ #
65
+ # g = ["a", "b", ["x", "y"]]
66
+ #
67
+ # CREDIT: Trans
68
+
69
+ def map(&block)
70
+ if block_given?
71
+ @enum.map do |e|
72
+ if Array === e || e.respond_to?(:to_ary)
73
+ e.to_ary.recursive.map(&block)
74
+ else
75
+ block.call(e)
76
+ end
77
+ end
78
+ else
79
+ to_enum(:map)
80
+ end
81
+ end
82
+
83
+ # Like #map, but will change the array in place.
84
+
85
+ def map!(&block)
86
+ replace(map(&block))
87
+ end
88
+
89
+ end
90
+
91
+ end
@@ -7,9 +7,8 @@ class Array
7
7
  # arr.recursively{|a| a.compact! }
8
8
  # => ["a", ["b", "c"]]
9
9
  #
10
- # TODO: Can this be generalized in Enumerbale?
11
-
12
10
  def recursively(&block)
11
+ warn "Use #recusive instead of #recursively for future versions"
13
12
  a = inject([]) do |array, value|
14
13
  if value.is_a?(Array)
15
14
  array << value.recursively(&block)
@@ -28,3 +27,4 @@ class Array
28
27
  end
29
28
 
30
29
  end
30
+
@@ -1,18 +1,35 @@
1
1
  class Array
2
2
 
3
+ # Returns a new array created by traversing the array and its
4
+ # sub-arrays, executing the given block on the elements.
3
5
  #
6
+ # h = ["A", "B", ["X", "Y"]]
7
+ #
8
+ # g = h.traverse{ |e| e.downcase }
9
+ #
10
+ # g = ["a", "b", ["x", "y"]]
11
+ #
12
+ # This is the same as <code>recursive.map</code> and will
13
+ # likely be deprecated in the future because of it.
14
+ #
15
+ # CREDIT: Trans
4
16
 
5
17
  def traverse(&block)
6
- map do |item|
7
- if item.is_a?(self.class)
8
- item.traverse(&block)
9
- else
10
- yield item
18
+ if block_given?
19
+ map do |e|
20
+ if e.respond_to?(:to_ary)
21
+ e.to_ary.traverse(&block)
22
+ else
23
+ block.call(e)
24
+ end
11
25
  end
26
+ else
27
+ to_enum(:traverse)
12
28
  end
13
29
  end
14
30
 
15
- #
31
+ # Like #recursive_map, but will change the
32
+ # array in place.
16
33
 
17
34
  def traverse!(&block)
18
35
  replace(traverse(&block))
@@ -0,0 +1 @@
1
+ require 'facets/enumerable/commonality'
@@ -4,7 +4,7 @@ module Enumerable
4
4
  # If no block is given objects are considered to be equal if they
5
5
  # return the same value for Object#hash and if obj1 == obj2.
6
6
  #
7
- # [1, 2, 2, 3, 4, 4].commonality # => { 2 => [2], 4 => [4] }
7
+ # [1, 2, 2, 3, 4, 4].commonality # => { 2 => [2, 2], 4 => [4, 4] }
8
8
  #
9
9
  # ["foo", "bar", "a"].commonality { |str| str.length }
10
10
  # # => { 3 => ["foo, "bar"] }
@@ -14,7 +14,7 @@ module Enumerable
14
14
  #
15
15
  # CREDIT: Florian Gross
16
16
 
17
- def commonality( &block )
17
+ def commonality(&block)
18
18
  had_no_block = !block
19
19
  block ||= lambda { |item| item }
20
20
  result = Hash.new { |hash, key| hash[key] = Array.new }
@@ -29,5 +29,7 @@ module Enumerable
29
29
  return result
30
30
  end
31
31
 
32
+ alias_method :collisions, :commonality
33
+
32
34
  end
33
35
 
@@ -1 +1,37 @@
1
- require 'facets/enumerable/mash'
1
+ module Enumerable
2
+
3
+ # Like <tt>#map</tt>/<tt>#collect</tt>, but generates a Hash. The block
4
+ # is expected to return two values: the key and the value for the new hash.
5
+ #
6
+ # numbers = (1..3)
7
+ # squares = numbers.graph{ |n| [n, n*n] } # { 1=>1, 2=>4, 3=>9 }
8
+ # sq_roots = numbers.graph{ |n| [n*n, n] } # { 1=>1, 4=>2, 9=>3 }
9
+ #
10
+ # CREDIT: Andrew Dudzik (adudzik), Trans
11
+
12
+ def graph(&yld)
13
+ if yld
14
+ h = {}
15
+ each do |*kv|
16
+ r = yld[*kv]
17
+ case r
18
+ when Hash
19
+ nk, nv = *r.to_a[0]
20
+ when Range
21
+ nk, nv = r.first, r.last
22
+ else
23
+ nk, nv = *r
24
+ end
25
+ h[nk] = nv
26
+ end
27
+ h
28
+ else
29
+ Enumerator.new(self,:graph)
30
+ end
31
+ end
32
+
33
+ # Alias for #graph, which stands for "map hash".
34
+ alias_method :mash, :graph
35
+
36
+ end
37
+
@@ -1,39 +1 @@
1
- module Enumerable
2
-
3
- # Like <tt>#map</tt>/<tt>#collect</tt>, but generates a Hash. The block
4
- # is expected to return two values: the key and the value for the new hash.
5
- #
6
- # numbers = (1..3)
7
- # squares = numbers.mash { |n| [n, n*n] } # { 1=>1, 2=>4, 3=>9 }
8
- # sq_roots = numbers.mash { |n| [n*n, n] } # { 1=>1, 4=>2, 9=>3 }
9
- #
10
- # The name "mash" stands for "map hash".
11
- #
12
- # CREDIT: Andrew Dudzik (adudzik), Trans
13
-
14
- def mash(&yld)
15
- if yld
16
- h = {}
17
- each do |*kv|
18
- r = yld[*kv]
19
- case r
20
- when Hash
21
- nk, nv = *r.to_a[0]
22
- when Range
23
- nk, nv = r.first, r.last
24
- else
25
- nk, nv = *r
26
- end
27
- h[nk] = nv
28
- end
29
- h
30
- else
31
- Enumerator.new(self,:mash)
32
- end
33
- end
34
-
35
- # Alias for #mash. This is the original name of this method.
36
- alias_method :graph, :mash
37
-
38
- end
39
-
1
+ require 'facets/enumerable/graph'
@@ -0,0 +1,75 @@
1
+ module Enumerable
2
+
3
+ def recursive(opts={})
4
+ Recursor.new(self, opts)
5
+ end
6
+
7
+ # Recursor "functor".
8
+ #
9
+ # NOTE: THIS IS A WORK IN PROGRESS!
10
+ #
11
+ class Recursor
12
+
13
+ def initialize(enum, opts)
14
+ @enum = enum
15
+ @opts = opts
16
+ end
17
+
18
+ # Recursive iteration over enumerables.
19
+ #
20
+ # [1, 2, [3, 4]].recursive.each{ |e| p e }
21
+ #
22
+ # produces
23
+ #
24
+ # 1
25
+ # 2
26
+ # 3
27
+ # 4
28
+ #
29
+ # NOTE: Technically this should check for the proper conversion
30
+ # method if applicable, eg. #to_ary for Array, rather than
31
+ # just checking the class type. In the future this may be
32
+ # generally supported if Facets ever adds a "class know-thy-self"
33
+ # library. In the meantime override in classes are required to
34
+ # incorporate this.
35
+
36
+ def each(&b)
37
+ @enum.each{ |*v| process(:each, *v, &b) }
38
+ end
39
+
40
+ # Recursive map.
41
+ #
42
+ # [1, 2, ['a', 'b']].recursive.map{ |e| e.succ }
43
+ # #=> [1, 2, ['b', 'c']]
44
+ #
45
+ def map(&b)
46
+ @enum.map{ |*v| process(:map, *v, &b) }
47
+ end
48
+
49
+ #
50
+ #def graph(&b)
51
+ # @enum.graph{ |*v| process(:graph, *v, &b) }
52
+ #end
53
+
54
+ private
55
+
56
+ #
57
+ def process(op, v, &b)
58
+ case v
59
+ when String # b/c of 1.8
60
+ b.call(v)
61
+ when @enum.class
62
+ v.recursive(@opts).send(op,&b)
63
+ else
64
+ #if @opts[:skip] && Enumerable === v
65
+ # v
66
+ #else
67
+ b.call(v)
68
+ #end
69
+ end
70
+ end
71
+
72
+ end
73
+
74
+ end
75
+
@@ -0,0 +1,30 @@
1
+ module Enumerable
2
+
3
+ # Recursively iterate over all Enumerable elements, or
4
+ # subset given <code>:type=>[type1, type2, ...]</code>.
5
+ #
6
+ # [1, 2, 8..9].visit{ |x| x.succ }
7
+ # # => [2, 3, [9, 10]]
8
+ #
9
+ def visit(opts={}, &block)
10
+ type = opts[:type] ? [opts[:type]].flatten : [Enumerable]
11
+ skip = opts[:skip]
12
+
13
+ map do |v|
14
+ case v
15
+ when String # b/c of 1.8
16
+ b.call(v)
17
+ when *type
18
+ v.recursive(opts).send(op,&b)
19
+ else
20
+ if skip && Enumerable === v
21
+ v
22
+ else
23
+ b.call(v)
24
+ end
25
+ end
26
+ end
27
+ end
28
+
29
+ end
30
+