facets 2.8.1 → 2.8.2

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -2,20 +2,20 @@ require 'facets/functor'
2
2
 
3
3
  module Enumerable
4
4
 
5
+ EWISE = {}
6
+
5
7
  # Returns an elementwise Functor designed to make R-like
6
- # elementwise operations possible.
8
+ # elementwise operations possible. This is very much like
9
+ # the #every method, but it treats array argument specially.
7
10
  #
8
- # [1,2].elementwise + 3 #=> [4,5]
9
- # [1,2].elementwise + [4,5] #=> [5,7]
10
- # [1,2].elementwise + [[4,5],3] #=> [[5,7],[4,5]
11
+ # [1,2].ewise + 3 #=> [4,5]
12
+ # [1,2].ewise + [4,5] #=> [5,7]
13
+ # [1,2].ewise + [[4,5],3] #=> [[5,7],[4,5]
11
14
  #
12
- #--
13
15
  # Special thanks to Martin DeMello for helping to develop this.
14
- #++
15
16
 
16
- def elementwise(count=1)
17
- @_elementwise_functor ||= []
18
- @_elementwise_functor[count] ||= Functor.new do |op,*args|
17
+ def ewise(count=1)
18
+ EWISE[[self,count]] ||= Functor.new do |op,*args|
19
19
  if args.empty?
20
20
  r = self
21
21
  count.times do
@@ -46,16 +46,22 @@ module Enumerable
46
46
  end
47
47
  end
48
48
 
49
- # Concise alias for #elementwise.
49
+ # Long-term for #ewise.
50
50
  #
51
51
  # a = [1,2]
52
- # a.ewise + 3 #=> [4,5]
53
- # a.ewise + [4,5] #=> [5,7]
54
- # a.ewise + [[4,5],3] #=> [[5,7],[4,5]
52
+ # a.elementwise + 3 #=> [4,5]
53
+ # a.elementwise + [4,5] #=> [5,7]
54
+ # a.elementwise + [[4,5],3] #=> [[5,7],[4,5]
55
55
  #
56
- # Note this used to be #ew as weel as the '%' operator.
57
- # Both of whihc are deprecated.
56
+ alias_method :elementwise, :ewise
58
57
 
59
- alias_method :ewise, :elementwise
58
+ # Operator equivalent of #elementwise.
59
+ #
60
+ # This was deprecated along with it's file "op_tilde.rb".
61
+ #
62
+ #def ~@
63
+ # ewise
64
+ #end
60
65
 
61
66
  end
67
+
@@ -0,0 +1,13 @@
1
+ module Enumerable
2
+
3
+ unless method_defined?(:exclude?) or defined?(::ActiveSupport) # 1.9 or ActiveSupport
4
+
5
+ # The inverse of #include?.
6
+ #
7
+ def exclude?(object)
8
+ !include?(object)
9
+ end
10
+
11
+ end
12
+
13
+ end
@@ -1,16 +1,20 @@
1
1
  module Enumerable
2
2
 
3
- # The block acts as an arbitrary filter on the data. Unlike
4
- # map, it can choose to drop elements from the result, and/or add
5
- # additional ones. The first object passed to the block is the receiver
6
- # of the output.
3
+ # The block acts as an arbitrary filter on the data. Unlike map,
4
+ # it can choose to drop elements from the result and/or add
5
+ # additional elements. The first object passed to the block is
6
+ # the receiver of the output.
7
7
  #
8
8
  # (1..1_000_000_000).
9
- # filter { |out,i| out << i if i % 2 == 0 }. # like select
10
- # filter { |out,i| out << i + 100 }. # like map
11
- # take(10).each { |i| puts i }
9
+ # filter{ |out,i| out << i if i % 2 == 0 }. # like select
10
+ # filter{ |out,i| out << i + 100 }. # like map
11
+ # take(10).each{ |i| puts i }
12
12
  #
13
- def filter(output=[])
13
+ # This is very similar to #each_with_object, but #filter handles
14
+ # argument better by reversing their order and using the splat
15
+ # operator.
16
+
17
+ def filter(output=[]) #:yeild:
14
18
  if block_given?
15
19
  each do |*input|
16
20
  yield(output, *input)
@@ -21,5 +25,11 @@ module Enumerable
21
25
  end
22
26
  end
23
27
 
28
+ # OLD NAME
29
+ # CREDIT: David Black, Louis J Scoras
30
+ #def injecting(k)
31
+ # each{ |i| yield(k, i) }; k
32
+ #end
33
+
24
34
  end
25
35
 
@@ -0,0 +1,37 @@
1
+ module Enumerable
2
+
3
+ # Yield each element to the block and return the result
4
+ # of the block when that result evaluates as true,
5
+ # terminating early like #detect and #find.
6
+ #
7
+ # obj1.foo? #=> false
8
+ # obj2.foo? #=> true
9
+ # obj2.foo #=> "value"
10
+ #
11
+ # [obj1, obj2].find_yield{ |obj| obj.foo if obj.foo? } #=> "value"
12
+ #
13
+ # Another example:
14
+ #
15
+ # [1,2,3,4,5].find_yield{ |i| j = i+1; j if j % 4 == 0 } #=> "5"
16
+ #
17
+ # If the block is never true, return the object given in the first parameter,
18
+ # or nil if none specified.
19
+ #
20
+ # [1,2,3].find_yield{ |_| false } #=> nil
21
+ # [false].find_yield(1){ |_| false } #=> 1
22
+ #
23
+ def find_yield(fallback=nil) #:yield:
24
+ each do |member|
25
+ result = yield(member)
26
+ return result if result
27
+ end
28
+ fallback
29
+ end
30
+
31
+ # DEPRECATE: This has been renamed to #find_yield.
32
+ def map_detect(fallback=nil)
33
+ find_yield(fallback)
34
+ end
35
+
36
+ end
37
+
@@ -1,28 +1 @@
1
- module Enumerable
2
-
3
- # Yield each element to the block. Returns the result of
4
- # the block when the block is true, terminating early as detect does.
5
- #
6
- # obj1.foo? #=> false
7
- # obj2.foo? #=> true
8
- #
9
- # obj2.foo #=> "a value"
10
- #
11
- # [obj1, obj2].map_detect { |obj| obj.foo if obj.foo? } #=> "a value"
12
- #
13
- # If the block is never true, return the object given in the first parameter,
14
- # or nil if none specified.
15
- #
16
- # [1,2,3].map_detect { |_| false } #=> nil
17
- # [false].map_detect(1) { |_| false } #=> 1
18
- #
19
- def map_detect(value_for_none_matching = nil)
20
- each do |member|
21
- if result = yield(member)
22
- return result
23
- end
24
- end
25
-
26
- value_for_none_matching
27
- end
28
- end
1
+ require 'facets/enumerable/find_yield'
@@ -9,8 +9,8 @@ module Enumerable
9
9
 
10
10
  def map_with_index
11
11
  r = []
12
- each_index do |i|
13
- r << yield(self[i], i)
12
+ each_with_index do |e, i|
13
+ r << yield(e, i)
14
14
  end
15
15
  r
16
16
  end
@@ -1,7 +1,7 @@
1
1
  require 'facets/functor'
2
2
 
3
3
  #--
4
- # TODO: Consider Enumerator methods
4
+ # TODO: Consider Enumerator methods.
5
5
  #++
6
6
 
7
7
  module Enumerable
@@ -22,7 +22,7 @@ module Enumerable
22
22
  # __send__(enum_method, *enum_args){ |x| x.__send__(op, *args) } #, &blk) }
23
23
  #end
24
24
  else
25
- @__per__ ||= Functor.new do |enum_method, *enum_args|
25
+ Functor.new do |enum_method, *enum_args|
26
26
  Permeator.new(self, enum_method, *enum_args)
27
27
  #Functor.new do |op, *args|
28
28
  # __send__(enum_method, *enum_args){ |x| x.__send__(op, *args) } #, &blk) }
@@ -0,0 +1,43 @@
1
+ module Enumerable
2
+
3
+ # A versitle compaction method. Like #map but used
4
+ # to filter out multiple items in a single step.
5
+ #
6
+ # Without +trash+ arguments +nil+ is assumed.
7
+ #
8
+ # [1, nil, 2].purge #=> [1,2]
9
+ #
10
+ # If +trash+ arguments are given, each argument is
11
+ # compared for a match using #==.
12
+ #
13
+ # (1..6).purge(3,4) #=> [1,2,5,6]
14
+ #
15
+ # If a block is given, the yield is used in the
16
+ # matching condition instead of the element itsef.
17
+ #
18
+ # (1..6).purge(0){ |n| n % 2 } #=> [1,3,5]
19
+ #
20
+ # NOTE: This could just as well be an override of the
21
+ # core #compact method, but to avoid potential issues
22
+ # associated with overriding core methods we use the
23
+ # alternate name #purge.
24
+ #
25
+ # CREDIT: Trans
26
+
27
+ def purge(*trash, &block)
28
+ trash = [nil] if trash.empty?
29
+ r = []
30
+ if block_given?
31
+ each do |e|
32
+ y = yield(e)
33
+ r << e unless trash.any?{|t| t == y}
34
+ end
35
+ else
36
+ each do |e|
37
+ r << e unless trash.any?{|t| t == e}
38
+ end
39
+ end
40
+ r
41
+ end
42
+
43
+ end
@@ -0,0 +1,70 @@
1
+ begin
2
+ require 'enumerator' #if RUBY_VERSION < 1.9
3
+ # for Ruby 1.8 -> 1.9 transition
4
+ Enumerator = Enumerable::Enumerator unless defined? ::Enumerator
5
+
6
+ class Enumerator
7
+
8
+ alias :old_initialize :initialize
9
+
10
+ # Provides the ruby-1.9 block form of Enumerator, where you can write:
11
+ #
12
+ # obj = Enumerator.new do |yielder|
13
+ # .. do stuff
14
+ # yielder.yield data # or: yielder << data
15
+ # .. etc
16
+ # end
17
+ #
18
+ # When obj.each is called, the block is run once. It should call
19
+ # yielder.yield with each item it wishes to generate.
20
+ #
21
+ # Example:
22
+ #
23
+ # fib = Enumerator.new { |y|
24
+ # a = b = 1
25
+ # loop {
26
+ # y << a
27
+ # a, b = b, a + b
28
+ # }
29
+ # }
30
+ #
31
+ # assert_equal [1, 1, 2, 3, 5, 8, 13, 21, 34, 55], fib.take(10)
32
+
33
+ def initialize(*args, &block)
34
+ if block_given?
35
+ @body = block
36
+ old_initialize(self, :_start)
37
+ else
38
+ old_initialize(*args)
39
+ end
40
+ end
41
+
42
+ def _start(*args,&receiver) #:nodoc:
43
+ @body.call(Yielder.new(receiver), *args)
44
+ end
45
+
46
+ # Wrapper to allow yielder.yield(output) or yielder << output
47
+ # in the same way as ruby-1.9
48
+
49
+ class Yielder #:nodoc:
50
+ def initialize(proc)
51
+ @proc = proc
52
+ end
53
+ def yield(*args)
54
+ @proc[*args]
55
+ end
56
+ alias :<< :yield
57
+ end
58
+
59
+ end
60
+
61
+ rescue LoadError # Ruby 1.9 already has it built-in.
62
+ end
63
+
64
+ path = __FILE__.chomp('.rb')
65
+ base = File.basename(path)
66
+ Dir[File.join(path, '*.rb')].each do |lib|
67
+ #require lib # why is this so much slower?
68
+ require "facets/#{base}/#{File.basename(lib)}"
69
+ end
70
+
@@ -0,0 +1,20 @@
1
+ begin
2
+ require 'enumerator' #if RUBY_VERSION < 1.9
3
+ # for Ruby 1.8 -> 1.9 transition
4
+ Enumerator = Enumerable::Enumerator unless defined? ::Enumerator
5
+ rescue LoadError # Ruby 1.9 already has it built-in.
6
+ end
7
+
8
+ require 'facets/functor'
9
+
10
+ class Enumerator
11
+
12
+ #
13
+ def fx
14
+ Functor.new do |op, *a|
15
+ each{ |e| e.send(op, *a) }
16
+ end
17
+ end
18
+
19
+ end
20
+
@@ -1,6 +1,6 @@
1
1
  class Integer
2
2
 
3
- # Is is a multiple of a given number?
3
+ # Is +self+ a multiple of a given number?
4
4
  #
5
5
  # 7.multiple?(2) #=> false
6
6
  # 8.multiple?(2) #=> true
@@ -8,7 +8,11 @@ class Integer
8
8
  # CREDIT: Trans
9
9
 
10
10
  def multiple?(number)
11
- self % number == 0
11
+ if number.zero?
12
+ zero? ? true : false
13
+ else
14
+ self % number == 0
15
+ end
12
16
  end
13
17
 
14
18
  end
@@ -0,0 +1,2 @@
1
+ require 'facets/kernel/true'
2
+
@@ -0,0 +1,26 @@
1
+ module Kernel
2
+
3
+ # Returns true is an object is class TrueClass,
4
+ # otherwise false.
5
+ #
6
+ # true.true? #=> true
7
+ # false.true? #=> false
8
+ # nil.true? #=> false
9
+ #
10
+ def true?
11
+ (true == self)
12
+ end
13
+
14
+ # Returns true is an object is class FalseClass,
15
+ # otherwise false.
16
+ #
17
+ # true.false? #=> false
18
+ # false.false? #=> true
19
+ # nil.false? #=> false
20
+ #
21
+ def false?
22
+ (false == self)
23
+ end
24
+
25
+ end
26
+
@@ -1,7 +1,7 @@
1
1
  class Numeric
2
2
 
3
- # Returns +self+.
4
-
3
+ # Returns +self+, useful for polymorphic cases.
4
+ #
5
5
  def length
6
6
  self
7
7
  end
@@ -0,0 +1,20 @@
1
+ class Numeric
2
+
3
+ # Returns the size of the string representation of
4
+ # a numerical value.
5
+ #
6
+ # 1.spacing #=> 1
7
+ # 10.spacing #=> 2
8
+ # 100.spacing #=> 3
9
+ # -100.spacing #=> 4
10
+ # 1.2.spacing #=> 3
11
+ #
12
+ # CREDIT: Victor H. Goff III
13
+
14
+ def spacing
15
+ to_s.length
16
+ end
17
+
18
+ end
19
+
20
+
@@ -0,0 +1,9 @@
1
+ class Proc
2
+
3
+ #
4
+ def bind_to(object)
5
+ Proc.new{object.instance_eval(&self)}
6
+ end
7
+
8
+ end
9
+