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