facets 2.8.1 → 2.8.2
Sign up to get free protection for your applications and to get access to all the features.
- data/HISTORY.rdoc +121 -91
- data/NOTES +13 -1
- data/demo/scenario_require.rdoc +0 -5
- data/lib/core/facets.rb +6 -382
- data/lib/core/facets/array.rb +4 -3
- data/lib/core/facets/array/product.rb +0 -9
- data/lib/core/facets/array/uniq_by.rb +18 -0
- data/lib/core/facets/binding/caller.rb +14 -18
- data/lib/core/facets/boolean.rb +75 -78
- data/lib/core/facets/denumerable.rb +3 -3
- data/lib/core/facets/dir/ascend.rb +2 -1
- data/lib/core/facets/enumerable/collapse.rb +12 -0
- data/lib/core/facets/enumerable/compact_map.rb +8 -4
- data/lib/core/facets/enumerable/defer.rb +3 -2
- data/lib/core/facets/enumerable/each_with_object.rb +38 -0
- data/lib/core/facets/enumerable/every.rb +4 -4
- data/lib/core/facets/enumerable/ewise.rb +22 -16
- data/lib/core/facets/enumerable/exclude.rb +13 -0
- data/lib/core/facets/enumerable/filter.rb +18 -8
- data/lib/core/facets/enumerable/find_yield.rb +37 -0
- data/lib/core/facets/enumerable/map_detect.rb +1 -28
- data/lib/core/facets/enumerable/map_with_index.rb +2 -2
- data/lib/core/facets/enumerable/per.rb +2 -2
- data/lib/core/facets/enumerable/purge.rb +43 -0
- data/lib/core/facets/enumerator.rb +70 -0
- data/lib/core/facets/enumerator/fx.rb +20 -0
- data/lib/core/facets/integer/multiple.rb +6 -2
- data/lib/core/facets/kernel/false.rb +2 -0
- data/lib/core/facets/kernel/true.rb +26 -0
- data/lib/core/facets/numeric/length.rb +2 -2
- data/lib/core/facets/numeric/spacing.rb +20 -0
- data/lib/core/facets/proc/bind_to.rb +9 -0
- data/lib/core/facets/string/exclude.rb +10 -0
- data/lib/core/facets/string/expand_tab.rb +6 -6
- data/lib/core/facets/time/future.rb +14 -0
- data/lib/core/facets/time/past.rb +1 -0
- data/lib/core/facets/unboundmethod/name.rb +22 -18
- data/lib/more/facets/date.rb +38 -3
- data/lib/more/facets/fileutils/cp_rx.rb +42 -0
- data/lib/more/facets/pathname.rb +1 -1
- data/meta/homepage +1 -1
- data/meta/released +1 -1
- data/meta/version +1 -1
- data/test/core/array/test_product.rb +0 -5
- data/test/core/enumerable/test_find_yield.rb +75 -0
- data/test/core/numeric/test_spacing.rb +12 -0
- data/test/core/unboundmethod/test_name.rb +3 -3
- metadata +36 -23
- data/MANIFEST +0 -756
- data/lib/core/facets/enumerable/collect.rb +0 -4
- data/lib/core/facets/enumerable/inject.rb +0 -30
- data/lib/core/facets/numeric/size.rb +0 -10
- data/lib/more/facets/enumerator.rb +0 -62
- data/lib/more/facets/tracepoint.rb +0 -209
- 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].
|
9
|
-
# [1,2].
|
10
|
-
# [1,2].
|
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
|
17
|
-
|
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
|
-
#
|
49
|
+
# Long-term for #ewise.
|
50
50
|
#
|
51
51
|
# a = [1,2]
|
52
|
-
# a.
|
53
|
-
# a.
|
54
|
-
# a.
|
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
|
-
|
57
|
-
# Both of whihc are deprecated.
|
56
|
+
alias_method :elementwise, :ewise
|
58
57
|
|
59
|
-
|
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
|
+
|
@@ -1,16 +1,20 @@
|
|
1
1
|
module Enumerable
|
2
2
|
|
3
|
-
# The block acts as an arbitrary filter on the data. Unlike
|
4
|
-
#
|
5
|
-
# additional
|
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
|
10
|
-
# filter
|
11
|
-
# take(10).each
|
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
|
-
|
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
|
-
|
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'
|
@@ -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
|
-
|
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
|
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
|
-
|
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,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
|
+
|
@@ -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
|
+
|