facets 2.8.2 → 2.8.3

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.
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
+