facets 2.8.1 → 2.8.2

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 (55) hide show
  1. data/HISTORY.rdoc +121 -91
  2. data/NOTES +13 -1
  3. data/demo/scenario_require.rdoc +0 -5
  4. data/lib/core/facets.rb +6 -382
  5. data/lib/core/facets/array.rb +4 -3
  6. data/lib/core/facets/array/product.rb +0 -9
  7. data/lib/core/facets/array/uniq_by.rb +18 -0
  8. data/lib/core/facets/binding/caller.rb +14 -18
  9. data/lib/core/facets/boolean.rb +75 -78
  10. data/lib/core/facets/denumerable.rb +3 -3
  11. data/lib/core/facets/dir/ascend.rb +2 -1
  12. data/lib/core/facets/enumerable/collapse.rb +12 -0
  13. data/lib/core/facets/enumerable/compact_map.rb +8 -4
  14. data/lib/core/facets/enumerable/defer.rb +3 -2
  15. data/lib/core/facets/enumerable/each_with_object.rb +38 -0
  16. data/lib/core/facets/enumerable/every.rb +4 -4
  17. data/lib/core/facets/enumerable/ewise.rb +22 -16
  18. data/lib/core/facets/enumerable/exclude.rb +13 -0
  19. data/lib/core/facets/enumerable/filter.rb +18 -8
  20. data/lib/core/facets/enumerable/find_yield.rb +37 -0
  21. data/lib/core/facets/enumerable/map_detect.rb +1 -28
  22. data/lib/core/facets/enumerable/map_with_index.rb +2 -2
  23. data/lib/core/facets/enumerable/per.rb +2 -2
  24. data/lib/core/facets/enumerable/purge.rb +43 -0
  25. data/lib/core/facets/enumerator.rb +70 -0
  26. data/lib/core/facets/enumerator/fx.rb +20 -0
  27. data/lib/core/facets/integer/multiple.rb +6 -2
  28. data/lib/core/facets/kernel/false.rb +2 -0
  29. data/lib/core/facets/kernel/true.rb +26 -0
  30. data/lib/core/facets/numeric/length.rb +2 -2
  31. data/lib/core/facets/numeric/spacing.rb +20 -0
  32. data/lib/core/facets/proc/bind_to.rb +9 -0
  33. data/lib/core/facets/string/exclude.rb +10 -0
  34. data/lib/core/facets/string/expand_tab.rb +6 -6
  35. data/lib/core/facets/time/future.rb +14 -0
  36. data/lib/core/facets/time/past.rb +1 -0
  37. data/lib/core/facets/unboundmethod/name.rb +22 -18
  38. data/lib/more/facets/date.rb +38 -3
  39. data/lib/more/facets/fileutils/cp_rx.rb +42 -0
  40. data/lib/more/facets/pathname.rb +1 -1
  41. data/meta/homepage +1 -1
  42. data/meta/released +1 -1
  43. data/meta/version +1 -1
  44. data/test/core/array/test_product.rb +0 -5
  45. data/test/core/enumerable/test_find_yield.rb +75 -0
  46. data/test/core/numeric/test_spacing.rb +12 -0
  47. data/test/core/unboundmethod/test_name.rb +3 -3
  48. metadata +36 -23
  49. data/MANIFEST +0 -756
  50. data/lib/core/facets/enumerable/collect.rb +0 -4
  51. data/lib/core/facets/enumerable/inject.rb +0 -30
  52. data/lib/core/facets/numeric/size.rb +0 -10
  53. data/lib/more/facets/enumerator.rb +0 -62
  54. data/lib/more/facets/tracepoint.rb +0 -209
  55. data/test/core/enumerable/test_map_detect.rb +0 -75
@@ -1,6 +1,7 @@
1
- dir, base = *File.split(__FILE__)
2
- base = base.chomp('.rb')
3
- Dir[File.join(dir, base, '*')].each do |lib|
1
+ path = __FILE__.chomp('.rb')
2
+ base = File.basename(path)
3
+ Dir[File.join(path, '*.rb')].each do |lib|
4
+ #require lib # why is this so much slower?
4
5
  require "facets/#{base}/#{File.basename(lib)}"
5
6
  end
6
7
 
@@ -27,14 +27,5 @@ class Array
27
27
 
28
28
  end
29
29
 
30
- # Operator alias for cross-product.
31
- #
32
- # a = [1,2] ** [4,5]
33
- # a #=> [[1, 4],[1, 5],[2, 4],[2, 5]]
34
- #
35
- # CREDIT: Trans
36
-
37
- alias_method :**, :product
38
-
39
30
  end
40
31
 
@@ -0,0 +1,18 @@
1
+ require 'facets/enumerable/uniq_by'
2
+
3
+ class Array
4
+
5
+ # Like #uniq, but determines uniqueness based on a given block.
6
+ #
7
+ # (-5..5).to_a.uniq_by {|i| i*i }
8
+ #
9
+ # produces
10
+ #
11
+ # [-5, -4, -3, -2, -1, 0]
12
+ #
13
+ def uniq_by! #:yield:
14
+ h = {}; replace(inject([]){|a,x| h[yield(x)] ||= a << x})
15
+ end
16
+
17
+ end
18
+
@@ -4,43 +4,39 @@ require 'facets/binding/callstack'
4
4
  class Binding
5
5
 
6
6
  # Returns the call stack, same format as Kernel#caller()
7
+ #
7
8
  def caller( skip=0 )
8
9
  eval("caller(#{skip})")
9
10
  end
10
11
 
11
- # Returns line number.
12
+ # Return the line number on which the binding was created.
13
+ #
12
14
  def __LINE__
13
- eval("__LINE__")
15
+ Kernel.eval("__LINE__", self)
14
16
  end
15
17
 
16
- # Returns file name.
18
+ # Returns file name in which the binding was created.
19
+ #
17
20
  def __FILE__
18
- eval("__FILE__")
21
+ Kernel.eval("__FILE__", self)
19
22
  end
20
23
 
21
- # Return the directory of the file.
22
- def __DIR__
23
- eval("File.dirname(__FILE__)")
24
+ # Return the directory of the file in which the binding was created.
25
+ #
26
+ def __DIR__
27
+ File.dirname(self.__FILE__)
24
28
  end
25
29
 
26
30
  # Retreive the current running method.
27
31
  #
28
- # def tester; p called; end
29
- # tester #=> :tester
30
- #
31
32
  def __callee__
32
- eval('__callee__')
33
+ Kernel.eval("__callee__", self)
33
34
  end
34
35
 
35
- # There is a lot of debate on what to call this.
36
- # +method_name+ differs from #called only by the fact
37
- # that it returns a string, rather then a symbol.
38
- #
39
- # def tester; p methodname; end
40
- # tester #=> "tester"
36
+ # Retreive the current running method.
41
37
  #
42
38
  def __method__
43
- eval('__method__')
39
+ Kernel.eval("__method__", self)
44
40
  end
45
41
 
46
42
  end
@@ -24,61 +24,8 @@
24
24
  # ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
25
25
  # FOR A PARTICULAR PURPOSE.
26
26
 
27
- #
28
- class String
29
-
30
- # Interpret common affirmative string meanings as true,
31
- # otherwise false. Balnk sapce and case are ignored.
32
- # The following strings that will return true:
33
- #
34
- # <tt>true</tt>,<tt>yes</tt>,<tt>on</tt>,<tt>t</tt>,<tt>1</tt>,<tt>y</tt>,<tt>==</tt>
35
- #
36
- # Examples:
37
- #
38
- # "true".to_b #=> true
39
- # "yes".to_b #=> true
40
- # "no".to_b #=> false
41
- # "123".to_b #=> false
42
- #
43
- def to_b
44
- case self.downcase.strip
45
- when 'true', 'yes', 'on', 't', '1', 'y', '=='
46
- return true
47
- when 'nil', 'null'
48
- return nil
49
- else
50
- return false
51
- end
52
- end
53
-
54
- end
55
-
56
-
57
- class Array
58
-
59
- # Boolean conversion for not empty?
60
- def to_b
61
- ! self.empty?
62
- end
63
-
64
- end
65
-
66
-
67
- class Numeric
68
-
69
- # Provides a boolean interpretation of self.
70
- # If self == 0 then false else true.
71
- #
72
- # 0.to_b #=> false
73
- # 1.to_b #=> true
74
- # 2.3.to_b #=> true
75
- #
76
- def to_b
77
- self == 0 ? false : true
78
- end
79
-
80
- end
81
-
27
+ require 'facets/kernel/true'
28
+ require 'facets/kernel/false'
82
29
 
83
30
  module Kernel
84
31
 
@@ -95,28 +42,6 @@ module Kernel
95
42
  self ? true : false
96
43
  end
97
44
 
98
- # Returns true is an object is class TrueClass,
99
- # otherwise false.
100
- #
101
- # true.true? #=> true
102
- # false.true? #=> false
103
- # nil.true? #=> false
104
- #
105
- def true?
106
- (true == self)
107
- end
108
-
109
- # Returns true is an object is class FalseClass,
110
- # otherwise false.
111
- #
112
- # true.false? #=> false
113
- # false.false? #=> true
114
- # nil.false? #=> false
115
- #
116
- def false?
117
- (false == self)
118
- end
119
-
120
45
  # Returns true is an object is class TrueClass
121
46
  # or FalseClass, otherwise false.
122
47
  #
@@ -133,24 +58,96 @@ end
133
58
 
134
59
  class Object
135
60
  def to_bool
136
- return true
61
+ true
137
62
  end
138
63
  end
139
64
 
65
+
140
66
  class TrueClass
141
67
  def to_bool
142
68
  self
143
69
  end
144
70
  end
145
71
 
72
+
146
73
  class FalseClass
147
74
  def to_bool
148
75
  self
149
76
  end
150
77
  end
151
78
 
79
+
152
80
  class NilClass
153
81
  def to_bool
154
82
  false
155
83
  end
156
84
  end
85
+
86
+
87
+ class String
88
+
89
+ # Interpret common affirmative string meanings as true,
90
+ # otherwise nil or false. Blank space and case are ignored.
91
+ # The following strings that will return true:
92
+ #
93
+ # true
94
+ # yes
95
+ # on
96
+ # t
97
+ # 1
98
+ # y
99
+ # ==
100
+ #
101
+ # The following strings will return nil:
102
+ #
103
+ # nil
104
+ # null
105
+ #
106
+ # All other strings return false.
107
+ #
108
+ # Examples:
109
+ #
110
+ # "true".to_b #=> true
111
+ # "yes".to_b #=> true
112
+ # "no".to_b #=> false
113
+ # "123".to_b #=> false
114
+ #
115
+ def to_b
116
+ case self.downcase.strip
117
+ when 'true', 'yes', 'on', 't', '1', 'y', '=='
118
+ return true
119
+ when 'nil', 'null'
120
+ return nil
121
+ else
122
+ return false
123
+ end
124
+ end
125
+
126
+ end
127
+
128
+
129
+ class Array
130
+
131
+ # Boolean conversion for not empty?
132
+ def to_b
133
+ ! self.empty?
134
+ end
135
+
136
+ end
137
+
138
+
139
+ class Numeric
140
+
141
+ # Provides a boolean interpretation of self.
142
+ # If self == 0 then false else true.
143
+ #
144
+ # 0.to_b #=> false
145
+ # 1.to_b #=> true
146
+ # 2.3.to_b #=> true
147
+ #
148
+ def to_b
149
+ self == 0 ? false : true
150
+ end
151
+
152
+ end
153
+
@@ -3,9 +3,9 @@ require 'facets/enumerator'
3
3
 
4
4
  # = Denumerable
5
5
  #
6
- # Classes which include Denumerable will get versions
7
- # of map, select etc. which return a Denumerator, so that they work
8
- # horizontally without creating intermediate arrays.
6
+ # Classes which include Denumerable will get versions of map,
7
+ # select, and so on, which return a Denumerator, so that they
8
+ # work horizontally without creating intermediate arrays.
9
9
  #
10
10
  module Denumerable
11
11
 
@@ -15,7 +15,7 @@ class Dir
15
15
  # /
16
16
  #
17
17
  # CREDIT: Daniel Berger, Jeffrey Schwab
18
-
18
+ #
19
19
  # TODO: make it work with windows too
20
20
  # use FileTest.root?
21
21
 
@@ -57,3 +57,4 @@ class Dir
57
57
  end
58
58
 
59
59
  end
60
+
@@ -0,0 +1,12 @@
1
+ class Array
2
+
3
+ # Simplify an array by flattening it then compacting it.
4
+ #
5
+ # [1,[2,nil,[3]],nil,4].collapse #=> [1,2,3,4]
6
+ #
7
+ def collapse
8
+ flatten.compact
9
+ end
10
+
11
+ end
12
+
@@ -3,7 +3,7 @@ module Enumerable
3
3
  # A more versitle #compact method. It can be used to
4
4
  # collect and filter items out in one single step.
5
5
  #
6
- # (1..3).compact_map do |n|
6
+ # [1,2,3].compact_map do |n|
7
7
  # n < 1 ? nil : n
8
8
  # end
9
9
  #
@@ -12,22 +12,26 @@ module Enumerable
12
12
  # [2,3]
13
13
  #
14
14
  # CREDIT: Trans
15
+ #
16
+ # DEPRECATE: This method should probably be removed b/c #purge
17
+ # does almost the same thing and enum.map{}.compact works too.
15
18
 
16
- def compact_map(trash=nil, &block)
19
+ def compact_map(&block)
17
20
  y = []
18
21
  if block_given?
19
22
  each do |*a|
20
23
  r = yield(*a)
21
- y << r unless trash == r
24
+ y << r unless r.nil?
22
25
  end
23
26
  else
24
27
  each do |r|
25
- y << r unless trash == r
28
+ y << r unless r.nil?
26
29
  end
27
30
  end
28
31
  y
29
32
  end
30
33
 
34
+ #
31
35
  alias_method :compact_collect, :compact_map
32
36
 
33
37
  end
@@ -31,13 +31,13 @@ module Enumerable
31
31
  if block_given?
32
32
  Denumerator.new do |output|
33
33
  each do |*input|
34
- yield output, *input
34
+ yield(output, *input)
35
35
  end
36
36
  end
37
37
  else
38
38
  Denumerator.new do |output|
39
39
  each do |*input|
40
- output.yield *input
40
+ output.yield(*input)
41
41
  end
42
42
  end
43
43
  end
@@ -45,6 +45,7 @@ module Enumerable
45
45
 
46
46
  end
47
47
 
48
+
48
49
  =begin
49
50
 
50
51
  TODO: (Programming Challenge) Dynamically create this in a single
@@ -0,0 +1,38 @@
1
+ module Enumerable
2
+
3
+ unless method_defined?(:each_with_object)
4
+
5
+ # A variation of #inject that saves one from having to
6
+ # return the aggregate/memo argument.
7
+ #
8
+ # Say we want to count characters in a string. Using
9
+ # the #each_with_object method we have:
10
+ #
11
+ # string.each_with_object(Hash.new(0)) do |c, h|
12
+ # h[c] += 1
13
+ # end
14
+ #
15
+ # versus using #inject which would be:
16
+ #
17
+ # string.inject(Hash.new(0)) do |h, c|
18
+ # h[c] +=1
19
+ # h
20
+ # end
21
+ #
22
+ # Notice that the order of the block parameters is reversed.
23
+ #
24
+ # This method used be called #injecting and had the same
25
+ # parameter order as #inject, but Ruby 1.9 has adopted this
26
+ # method, so we support it instead.
27
+
28
+ def each_with_object(memo) #:yield:
29
+ each do |element|
30
+ yield(element, memo)
31
+ end
32
+ memo
33
+ end
34
+
35
+ end
36
+
37
+ end
38
+
@@ -8,25 +8,25 @@ module Enumerable
8
8
  # r = [1,2,3].every + 3 #=> [4,5,6]
9
9
  #
10
10
  def every
11
- @_every ||= per(:map)
11
+ per(:map)
12
12
  end
13
13
 
14
14
  # In place version of #every.
15
15
  #
16
16
  def every!
17
17
  raise NoMethodError unless respond_to?(:map!)
18
- @_every_inplace ||= per(:map!)
18
+ per(:map!)
19
19
  end
20
20
 
21
21
  #def every
22
- # @_every ||= Functor.new do |op,*args|
22
+ # Functor.new do |op,*args|
23
23
  # map{ |a| a.send(op,*args) }
24
24
  # end
25
25
  #end
26
26
 
27
27
  #def every!
28
28
  # raise NoMethodError unless respond_to?(:map!)
29
- # @_every_inplace ||= Functor.new do |op,*args|
29
+ # Functor.new do |op,*args|
30
30
  # map!{ |a| a.send(op,*args) }
31
31
  # end
32
32
  #end