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.
- 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
data/lib/core/facets/array.rb
CHANGED
@@ -1,6 +1,7 @@
|
|
1
|
-
|
2
|
-
base =
|
3
|
-
Dir[File.join(
|
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
|
|
@@ -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
|
-
#
|
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
|
-
|
23
|
-
|
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(
|
33
|
+
Kernel.eval("__callee__", self)
|
33
34
|
end
|
34
35
|
|
35
|
-
#
|
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(
|
39
|
+
Kernel.eval("__method__", self)
|
44
40
|
end
|
45
41
|
|
46
42
|
end
|
data/lib/core/facets/boolean.rb
CHANGED
@@ -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
|
-
|
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
|
-
|
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
|
-
#
|
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
|
|
@@ -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
|
-
#
|
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(
|
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
|
24
|
+
y << r unless r.nil?
|
22
25
|
end
|
23
26
|
else
|
24
27
|
each do |r|
|
25
|
-
y << r unless
|
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
|
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
|
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
|
-
|
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
|
-
|
18
|
+
per(:map!)
|
19
19
|
end
|
20
20
|
|
21
21
|
#def every
|
22
|
-
#
|
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
|
-
#
|
29
|
+
# Functor.new do |op,*args|
|
30
30
|
# map!{ |a| a.send(op,*args) }
|
31
31
|
# end
|
32
32
|
#end
|