quality_extensions 1.1.4 → 1.1.6
Sign up to get free protection for your applications and to get access to all the features.
- data/lib/Xfind_bug_test.rb +28 -0
- data/lib/quality_extensions/array/all_same.rb +40 -0
- data/lib/quality_extensions/array/delete_if_bang.rb +145 -0
- data/lib/quality_extensions/array/expand_ranges.rb +3 -53
- data/lib/quality_extensions/array/include_any_of.rb +23 -0
- data/lib/quality_extensions/array/justify.rb +305 -0
- data/lib/quality_extensions/array/{average.rb → mean.rb} +1 -1
- data/lib/quality_extensions/array/select_if_bang.rb +0 -0
- data/lib/quality_extensions/array/sum.rb +30 -0
- data/lib/quality_extensions/enumerable/all_same.rb +43 -0
- data/lib/quality_extensions/enumerable/group_by_and_map.rb +110 -0
- data/lib/quality_extensions/enumerable/select_bang.rb +49 -0
- data/lib/quality_extensions/enumerable/select_while.rb +337 -52
- data/lib/quality_extensions/enumerable/select_with_index.rb +145 -0
- data/lib/quality_extensions/hash/hash_select.rb +5 -2
- data/lib/quality_extensions/hash/merge_if.rb +48 -0
- data/lib/quality_extensions/kernel/example_printer.rb +10 -3
- data/lib/quality_extensions/kernel/require_all.rb +24 -8
- data/lib/quality_extensions/kernel/sleep_loudly.rb +108 -0
- data/lib/quality_extensions/kernel/uninterruptable.rb +22 -0
- data/lib/quality_extensions/matrix/indexable.rb +68 -0
- data/lib/quality_extensions/matrix/linked_vectors.rb +137 -0
- data/lib/quality_extensions/module/class_methods.rb +2 -0
- data/lib/quality_extensions/object/non.rb +12 -0
- data/lib/quality_extensions/pathname.rb +435 -7
- data/lib/quality_extensions/range_list.rb +222 -0
- data/lib/quality_extensions/safe_nil.rb +5 -3
- data/lib/quality_extensions/string/each_char_with_index.rb +1 -2
- data/lib/quality_extensions/string/integer_eh.rb +3 -0
- data/lib/quality_extensions/string/numeric_eh.rb +74 -0
- data/lib/quality_extensions/string/safe_in_comment.rb +38 -0
- data/lib/quality_extensions/string/safe_numeric_conversion.rb +102 -0
- data/lib/quality_extensions/string/shell_escape.rb +4 -4
- data/lib/quality_extensions/string/with_knowledge_of_color.rb +8 -0
- data/lib/quality_extensions/table.rb +116 -0
- data/lib/quality_extensions/template.rb +4 -5
- data/lib/quality_extensions/template.rb_test_unit.rb +33 -0
- data/lib/quality_extensions/test/difference_highlighting-minitest.rb +321 -0
- data/lib/quality_extensions/test/difference_highlighting-test_unit.rb +325 -0
- data/lib/quality_extensions/test/difference_highlighting.rb +6 -314
- data/lib/quality_extensions/timeout/countdown_timer.rb +1 -0
- data/lib/quality_extensions/vector/enumerable.rb +51 -0
- metadata +35 -5
@@ -0,0 +1,28 @@
|
|
1
|
+
#!/usr/bin/ruby
|
2
|
+
|
3
|
+
require 'find'
|
4
|
+
require 'pathname'
|
5
|
+
require 'tempfile'
|
6
|
+
|
7
|
+
require 'test/unit'
|
8
|
+
|
9
|
+
class TheTest < Test::Unit::TestCase
|
10
|
+
|
11
|
+
def test_basic
|
12
|
+
Find.find('.') do |path|
|
13
|
+
puts path
|
14
|
+
sleep 1
|
15
|
+
redo
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
# def test_pathname
|
20
|
+
# Pathname.new('.').find do |path|
|
21
|
+
# catch :something do
|
22
|
+
# puts path
|
23
|
+
# throw :something
|
24
|
+
# end
|
25
|
+
# end
|
26
|
+
# end
|
27
|
+
|
28
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?::
|
6
|
+
# Developer notes::
|
7
|
+
# History::
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Enumerable
|
11
|
+
def all_same?
|
12
|
+
all? {|a| a == first}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
# _____ _
|
20
|
+
# |_ _|__ ___| |_
|
21
|
+
# | |/ _ \/ __| __|
|
22
|
+
# | | __/\__ \ |_
|
23
|
+
# |_|\___||___/\__|
|
24
|
+
#
|
25
|
+
=begin test
|
26
|
+
require 'spec/autorun'
|
27
|
+
|
28
|
+
describe 'Enumerable#all_same?' do
|
29
|
+
it 'works with arrays' do
|
30
|
+
[1, 2].all_same?.should == false
|
31
|
+
[1, 1].all_same?.should == true
|
32
|
+
end
|
33
|
+
|
34
|
+
it 'works with Enumerators' do
|
35
|
+
'a b'.chars.all_same?.should == false
|
36
|
+
'aaa'.chars.all_same?.should == true
|
37
|
+
end
|
38
|
+
end
|
39
|
+
=end
|
40
|
+
|
@@ -0,0 +1,145 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes
|
6
|
+
# Developer notes::
|
7
|
+
# Changes::
|
8
|
+
#++
|
9
|
+
|
10
|
+
require 'facets/array/delete_values'
|
11
|
+
|
12
|
+
class Array
|
13
|
+
# Like partition, in that it creates two arrays, the first containing the elements of
|
14
|
+
# <i>enum</i> for which the block evaluates to false, the second
|
15
|
+
# containing the rest, only instead of returning both arrays, it changes +self+ for the first array (those for which the block evaluates to false)
|
16
|
+
# and thus only needs to return the second array (those for which the block evaluates to true)
|
17
|
+
#
|
18
|
+
# this is analagous to what shift (or pop) does: it shifts (or pops) an element off of a collection and simultaneously returns that element which was shifted (or popped) off
|
19
|
+
#
|
20
|
+
# Example:
|
21
|
+
#
|
22
|
+
# orig_a = a = (1..6).to_a
|
23
|
+
# b = a.select_if! {|i| i % 3 == 0} # => [1, 2, 4, 5]
|
24
|
+
# a # => [3, 6]
|
25
|
+
#
|
26
|
+
# This is identical to doing this:
|
27
|
+
# orig_a = a = (1..6).to_a
|
28
|
+
# a, b = a.partition {|i| i % 3 == 0}
|
29
|
+
# a # => [3, 6]
|
30
|
+
# b # => [1, 2, 4, 5]
|
31
|
+
#
|
32
|
+
# except that in the case of partition, orig_a and a are now to different objects, whereas with select_if, a remains the same object and is modified in place.
|
33
|
+
#
|
34
|
+
# name?:
|
35
|
+
# modify!
|
36
|
+
# select_if_returning_deleted
|
37
|
+
# shift_if :)
|
38
|
+
#
|
39
|
+
def select_if!(&block)
|
40
|
+
d = []
|
41
|
+
each{ |v| d << v unless yield v}
|
42
|
+
delete_values(*d)
|
43
|
+
d
|
44
|
+
end
|
45
|
+
|
46
|
+
#
|
47
|
+
# Note that self is not modified (the values are not deleted) until it has finished iterating through elements and has given a chance for you to decide the fate of each element.
|
48
|
+
# (So if, for instance, you want to refer to the previous value, you can do that with select_if_with_index! by using array[i-1], even if array[i-1] is "scheduled for deletion", because it will not have been deleted yet.)
|
49
|
+
#
|
50
|
+
# Example:
|
51
|
+
# args_for_vim = ARGV.delete_if! {|arg, i|
|
52
|
+
# arg =~ /^-c/ || ARGV[i-1] =~ /^-c/ \
|
53
|
+
# || arg =~ /^\+/
|
54
|
+
# }
|
55
|
+
#
|
56
|
+
def select_if_with_index!(&block)
|
57
|
+
d = []
|
58
|
+
each_with_index{ |v,i| d << v unless yield v,i}
|
59
|
+
delete_values(*d)
|
60
|
+
d
|
61
|
+
end
|
62
|
+
|
63
|
+
# Like partition, in that it creates two arrays, the first containing the elements of
|
64
|
+
# <i>enum</i> for which the block evaluates to false, the second
|
65
|
+
# containing the rest, only instead of returning both arrays, it changes +self+ for the first array (those for which the block evaluates to false)
|
66
|
+
# and thus only needs to return the second array (those for which the block evaluates to true)
|
67
|
+
# (1..6).partition {|i| i % 3 == 0} # => [[3, 6], [1, 2, 4, 5]]
|
68
|
+
#
|
69
|
+
# a = (1..6).to_a
|
70
|
+
# a.delete_if! {|i| i % 3 == 0} # => [3, 6]
|
71
|
+
# a # => [1, 2, 4, 5]
|
72
|
+
#
|
73
|
+
# similar to delete_if / reject!, but modifies self in place (removes elements from self) and rather than simply discarding the deleted elements, it returns an array containing those elements removed (similar to partition)
|
74
|
+
#
|
75
|
+
# a more generic version of Facets' delete_values; that can only be used to delete if a value matches exactly; this can use any arbitrary comparison to determine whether or not to delete element
|
76
|
+
#
|
77
|
+
# name?:
|
78
|
+
# modify!
|
79
|
+
# delete_if_returning_deleted
|
80
|
+
# shift_unless :)
|
81
|
+
#
|
82
|
+
def delete_if!(&block)
|
83
|
+
d = []
|
84
|
+
#each{ |v| d << delete(v) if yield v; puts "yield #{v} returned #{yield v}"} # didn't work because the deleting messed up the each and not all elements were visited
|
85
|
+
each{ |v| d << v if yield v}
|
86
|
+
delete_values(*d)
|
87
|
+
d
|
88
|
+
end
|
89
|
+
end
|
90
|
+
|
91
|
+
|
92
|
+
|
93
|
+
|
94
|
+
|
95
|
+
|
96
|
+
|
97
|
+
# _____ _
|
98
|
+
# |_ _|__ ___| |_
|
99
|
+
# | |/ _ \/ __| __|
|
100
|
+
# | | __/\__ \ |_
|
101
|
+
# |_|\___||___/\__|
|
102
|
+
#
|
103
|
+
=begin test
|
104
|
+
require 'spec'
|
105
|
+
|
106
|
+
describe '' do
|
107
|
+
it "delete_if! { el == 'a'}" do
|
108
|
+
orig = %w[a b c]
|
109
|
+
deleted = orig.delete_if! {|el| el == 'a'}
|
110
|
+
|
111
|
+
deleted.should == %w[a]
|
112
|
+
orig .should == %w[b c]
|
113
|
+
end
|
114
|
+
|
115
|
+
it "delete_if! { ... == el.upcase}" do
|
116
|
+
orig = %w[a b A B]
|
117
|
+
deleted = orig.delete_if! {|el| el.upcase == el}
|
118
|
+
|
119
|
+
deleted.should == %w[A B]
|
120
|
+
orig .should == %w[a b]
|
121
|
+
end
|
122
|
+
|
123
|
+
it "delete_if! { ... == i % 3 == 0}" do
|
124
|
+
a = (1..6).to_a
|
125
|
+
(d = a.delete_if! {|i| i % 3 == 0}).should == [3, 6]
|
126
|
+
a .should == [1, 2, 4, 5]
|
127
|
+
end
|
128
|
+
|
129
|
+
it "select_if! { ... == i % 3 == 0}" do
|
130
|
+
orig_a = a = (1..6).to_a
|
131
|
+
(d = a.select_if! {|i| i % 3 == 0}).should == [1, 2, 4, 5]
|
132
|
+
a .should == [3, 6]
|
133
|
+
a.object_id.should == orig_a.object_id
|
134
|
+
end
|
135
|
+
|
136
|
+
it "unlike when using partition, keeps its identity" do
|
137
|
+
orig_a = a = (1..6).to_a
|
138
|
+
a, b = a.partition {|i| i % 3 == 0}
|
139
|
+
a.should == [3, 6]
|
140
|
+
b.should == [1, 2, 4, 5]
|
141
|
+
a.object_id.should_not == orig_a.object_id
|
142
|
+
end
|
143
|
+
|
144
|
+
end
|
145
|
+
=end
|
@@ -1,54 +1,4 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
|
4
|
-
# License:: Ruby License
|
5
|
-
# Submit to Facets?:: Yes.
|
6
|
-
#++
|
7
|
-
|
8
|
-
$LOAD_PATH << File.expand_path(File.join(File.dirname(__FILE__), '..', '..'))
|
9
|
-
require 'rubygems'
|
10
|
-
require 'facets/kernel/silence'
|
11
|
-
|
12
|
-
class Array
|
13
|
-
# Expands (calls +to_a+ on) all Ranges contained in this array, replacing the range with the list of *elements* that the range represents.
|
14
|
-
#
|
15
|
-
# This is especially useful when you want to have "discontiguous ranges" like [1..3, 5..7]...
|
16
|
-
#
|
17
|
-
# [1..3, 5..7].expand_ranges
|
18
|
-
# => [1, 2, 3, 5, 6, 7]
|
19
|
-
#
|
20
|
-
def expand_ranges
|
21
|
-
new_array = []
|
22
|
-
each do |item|
|
23
|
-
silence_warnings do # Object.to_a: warning: default `to_a' will be obsolete
|
24
|
-
if item.respond_to?(:to_a)
|
25
|
-
new_array.concat item.to_a
|
26
|
-
else
|
27
|
-
new_array.concat [item]
|
28
|
-
end
|
29
|
-
end
|
30
|
-
end
|
31
|
-
new_array
|
32
|
-
end
|
33
|
-
end
|
34
|
-
|
35
|
-
# _____ _
|
36
|
-
# |_ _|__ ___| |_
|
37
|
-
# | |/ _ \/ __| __|
|
38
|
-
# | | __/\__ \ |_
|
39
|
-
# |_|\___||___/\__|
|
40
|
-
#
|
41
|
-
=begin test
|
42
|
-
require 'test/unit'
|
43
|
-
|
44
|
-
class TheTest < Test::Unit::TestCase
|
45
|
-
def test_1
|
46
|
-
assert_equal [1, 2, 3], [1, 2, 3].expand_ranges
|
47
|
-
end
|
48
|
-
def test_2
|
49
|
-
assert_equal [1, 2, 3], [1..3].expand_ranges
|
50
|
-
assert_equal [1, 2, 3, 5, 6, 7], [1..3, 5..7].expand_ranges
|
51
|
-
end
|
52
|
-
end
|
53
|
-
=end
|
1
|
+
# Alias for:
|
2
|
+
require 'facets/kernel/require_local'
|
3
|
+
require_local '../range_list'
|
54
4
|
|
@@ -0,0 +1,23 @@
|
|
1
|
+
Welcome!
|
2
|
+
irb -> [1,2,5].include_any_of? [3,5]
|
3
|
+
NoMethodError: undefined method `include_any_of?' for [1, 2, 5]:Array
|
4
|
+
from (irb):1
|
5
|
+
from /usr/local/bin/irb:12:in `<main>'
|
6
|
+
irb -> [1,2,5] & [3,5]
|
7
|
+
=> [5]
|
8
|
+
|
9
|
+
irb -> !!([1,2,5] & [3,5])
|
10
|
+
=> true
|
11
|
+
|
12
|
+
irb -> [1,2,5] & [3,4]
|
13
|
+
=> []
|
14
|
+
|
15
|
+
irb -> !!([1,2,5] & [3,4])
|
16
|
+
=> true
|
17
|
+
|
18
|
+
irb -> ([1,2,5] & [3,4]).any?
|
19
|
+
=> false
|
20
|
+
|
21
|
+
irb -> ([1,2,5] & [3,5]).any?
|
22
|
+
=> true
|
23
|
+
|
@@ -0,0 +1,305 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?::
|
6
|
+
# Developer notes::
|
7
|
+
# History::
|
8
|
+
# To do::
|
9
|
+
#++
|
10
|
+
|
11
|
+
require 'rubygems'
|
12
|
+
require 'facets/kernel/deep_copy'
|
13
|
+
require File.dirname(__FILE__) + '/../vector/enumerable'
|
14
|
+
require File.dirname(__FILE__) + '/../matrix/linked_vectors'
|
15
|
+
|
16
|
+
class Array
|
17
|
+
# In each column of a table (2-dimensional array) of strings, pads the string with +padstr+ (using ljust) so that all strings in that column have the same length.
|
18
|
+
#
|
19
|
+
# [['a', 'bb'],
|
20
|
+
# ['aaa', 'b' ]].ljust_columns
|
21
|
+
# => [['a ', 'bb'],
|
22
|
+
# ['aaa', 'b ']]
|
23
|
+
#
|
24
|
+
# The new values in the table will be strings even if they were not originally (1 might turn into '1 ', for example).
|
25
|
+
#
|
26
|
+
def ljust_columns(padstr = ' ')
|
27
|
+
new = self.deep_copy
|
28
|
+
new.ljust_columns!(padstr)
|
29
|
+
new
|
30
|
+
end
|
31
|
+
|
32
|
+
# Original version without using Matrix:
|
33
|
+
# def ljust_columns!(padstr = ' ')
|
34
|
+
# self[0].each_index do |c|
|
35
|
+
# max_length_in_col = max_by { |row|
|
36
|
+
# row[c].to_s.length
|
37
|
+
# }[c].to_s.length
|
38
|
+
# each { |row|
|
39
|
+
# row[c] = row[c].to_s.ljust(max_length_in_col, padstr)
|
40
|
+
# }
|
41
|
+
# end
|
42
|
+
# self
|
43
|
+
# end
|
44
|
+
|
45
|
+
# In-place version of ljust_columns.
|
46
|
+
#
|
47
|
+
def ljust_columns!(padstr = ' ')
|
48
|
+
matrix = Matrix[*self]
|
49
|
+
matrix.column_vectors.each do |column|
|
50
|
+
max_length_in_col = column.max_by { |el|
|
51
|
+
el.to_s.length
|
52
|
+
}.to_s.length
|
53
|
+
column.each_with_index { |el, i|
|
54
|
+
column[i] = el.to_s.ljust(max_length_in_col, padstr)
|
55
|
+
}
|
56
|
+
end
|
57
|
+
self
|
58
|
+
end
|
59
|
+
|
60
|
+
# In each row of a table (2-dimensional array) of strings, pads the string with +padstr+ (using ljust) so that all strings in that row have the same length.
|
61
|
+
#
|
62
|
+
# [['a' , 'aa' , 'a' ],
|
63
|
+
# ['bbb', 'b' , 'b' ]].ljust_rows
|
64
|
+
# => [['a ' , 'aa' , 'a ' ],
|
65
|
+
# ['bbb', 'b ', 'b ']]
|
66
|
+
#
|
67
|
+
# The new values in the table will be strings even if they were not originally (1 might turn into '1 ', for example).
|
68
|
+
#
|
69
|
+
def ljust_rows(padstr = ' ')
|
70
|
+
new = self.deep_copy
|
71
|
+
new.ljust_rows!(padstr)
|
72
|
+
new
|
73
|
+
end
|
74
|
+
|
75
|
+
# Original version without using Matrix:
|
76
|
+
# def ljust_rows!(padstr = ' ')
|
77
|
+
# c_count = self[0].size # We assume all rows have the same number of columns
|
78
|
+
# self.each_index do |r|
|
79
|
+
# max_length_in_row = 0.upto(c_count - 1).inject(0) { |memo, c|
|
80
|
+
# [self[r][c].to_s.length, memo].max
|
81
|
+
# }
|
82
|
+
# 0.upto(c_count - 1).each { |c|
|
83
|
+
# self[r][c] = self[r][c].to_s.ljust(max_length_in_row, padstr)
|
84
|
+
# }
|
85
|
+
# end
|
86
|
+
# self
|
87
|
+
# end
|
88
|
+
|
89
|
+
# In-place version of ljust_rows.
|
90
|
+
#
|
91
|
+
def ljust_rows!(padstr = ' ')
|
92
|
+
matrix = Matrix[*self]
|
93
|
+
matrix.row_vectors.each do |row|
|
94
|
+
max_length_in_row = row.max_by { |el|
|
95
|
+
el.to_s.length
|
96
|
+
}.to_s.length
|
97
|
+
row.each_with_index { |el, i|
|
98
|
+
row[i] = el.to_s.ljust(max_length_in_row, padstr)
|
99
|
+
}
|
100
|
+
end
|
101
|
+
self
|
102
|
+
end
|
103
|
+
|
104
|
+
#-------------------------------------------------------------------------------------------------
|
105
|
+
# Maintenance note: rjust versions are simply copied and pasted with the substitution s/ljust/rjust/g applied and the descriptions and examples changed.
|
106
|
+
|
107
|
+
# In each column of a table (2-dimensional array) of strings, pads the string with +padstr+ (using rjust) so that all strings in that column have the same length.
|
108
|
+
#
|
109
|
+
# [[ 'a', 'bb'],
|
110
|
+
# ['aaa', 'b']].rjust_columns
|
111
|
+
# => [[' a', 'bb'],
|
112
|
+
# ['aaa', ' b']]
|
113
|
+
#
|
114
|
+
# The new values in the table will be strings even if they were not originally (1 might turn into '1 ', for example).
|
115
|
+
#
|
116
|
+
def rjust_columns(padstr = ' ')
|
117
|
+
new = self.deep_copy
|
118
|
+
new.rjust_columns!(padstr)
|
119
|
+
new
|
120
|
+
end
|
121
|
+
|
122
|
+
# In-place version of rjust_columns.
|
123
|
+
#
|
124
|
+
def rjust_columns!(padstr = ' ')
|
125
|
+
matrix = Matrix[*self]
|
126
|
+
matrix.column_vectors.each do |column|
|
127
|
+
max_length_in_col = column.max_by { |el|
|
128
|
+
el.to_s.length
|
129
|
+
}.to_s.length
|
130
|
+
column.each_with_index { |el, i|
|
131
|
+
column[i] = el.to_s.rjust(max_length_in_col, padstr)
|
132
|
+
}
|
133
|
+
end
|
134
|
+
self
|
135
|
+
end
|
136
|
+
|
137
|
+
# In each row of a table (2-dimensional array) of strings, pads the string with +padstr+ (using rjust) so that all strings in that row have the same length.
|
138
|
+
#
|
139
|
+
# [[ 'a', 'aa', 'a'],
|
140
|
+
# ['bbb', 'b', 'b']].rjust_rows
|
141
|
+
# => [[ ' a', 'aa', ' a'],
|
142
|
+
# ['bbb', ' b', ' b']]
|
143
|
+
#
|
144
|
+
# The new values in the table will be strings even if they were not originally (1 might turn into '1 ', for example).
|
145
|
+
#
|
146
|
+
def rjust_rows(padstr = ' ')
|
147
|
+
new = self.deep_copy
|
148
|
+
new.rjust_rows!(padstr)
|
149
|
+
new
|
150
|
+
end
|
151
|
+
|
152
|
+
# In-place version of rjust_rows.
|
153
|
+
#
|
154
|
+
def rjust_rows!(padstr = ' ')
|
155
|
+
matrix = Matrix[*self]
|
156
|
+
matrix.row_vectors.each do |row|
|
157
|
+
max_length_in_row = row.max_by { |el|
|
158
|
+
el.to_s.length
|
159
|
+
}.to_s.length
|
160
|
+
row.each_with_index { |el, i|
|
161
|
+
row[i] = el.to_s.rjust(max_length_in_row, padstr)
|
162
|
+
}
|
163
|
+
end
|
164
|
+
self
|
165
|
+
end
|
166
|
+
|
167
|
+
end
|
168
|
+
|
169
|
+
# _____ _
|
170
|
+
# |_ _|__ ___| |_
|
171
|
+
# | |/ _ \/ __| __|
|
172
|
+
# | | __/\__ \ |_
|
173
|
+
# |_|\___||___/\__|
|
174
|
+
#
|
175
|
+
=begin test
|
176
|
+
require 'spec'
|
177
|
+
require 'pp'
|
178
|
+
|
179
|
+
describe 'Array.ljust_columns!' do
|
180
|
+
before do
|
181
|
+
@array = [['a', 'bb', 'c'],
|
182
|
+
['aaa', 'b', 'c']]
|
183
|
+
@array2 = [['a', 'bb'],
|
184
|
+
['aaa', 'b' ],
|
185
|
+
['a', 'b' ]]
|
186
|
+
end
|
187
|
+
|
188
|
+
it 'basic' do
|
189
|
+
@array.ljust_columns!
|
190
|
+
@array.should == [['a ', 'bb', 'c'],
|
191
|
+
['aaa', 'b ', 'c']]
|
192
|
+
end
|
193
|
+
|
194
|
+
it 'rotated' do
|
195
|
+
@array2.ljust_columns!
|
196
|
+
@array2.should == [['a ', 'bb'],
|
197
|
+
['aaa', 'b ' ],
|
198
|
+
['a ', 'b ' ]]
|
199
|
+
end
|
200
|
+
|
201
|
+
it 'with non-string receiver array' do
|
202
|
+
@array = [[1, 2], [1, 22]]
|
203
|
+
@array.ljust_columns!
|
204
|
+
@array.should == [['1', '2 '], ['1', '22']]
|
205
|
+
end
|
206
|
+
|
207
|
+
it 'with different padding character' do
|
208
|
+
@array.ljust_columns!('_')
|
209
|
+
@array.should == [['a__', 'bb', 'c'],
|
210
|
+
['aaa', 'b_', 'c']]
|
211
|
+
end
|
212
|
+
end
|
213
|
+
|
214
|
+
describe 'Array.ljust_columns' do
|
215
|
+
before do
|
216
|
+
@array = [['a', 'bb', 'c'],
|
217
|
+
['aaa', 'b', 'c' ]]
|
218
|
+
end
|
219
|
+
|
220
|
+
it 'should not modify receiver array' do
|
221
|
+
@array.should == [['a' , 'bb', 'c'],
|
222
|
+
['aaa', 'b' , 'c']]
|
223
|
+
ret = @array.ljust_columns
|
224
|
+
ret.should == [['a ', 'bb', 'c'],
|
225
|
+
['aaa', 'b ', 'c']]
|
226
|
+
# Should not have modified @array
|
227
|
+
@array.should == [['a' , 'bb', 'c'],
|
228
|
+
['aaa', 'b' , 'c']]
|
229
|
+
end
|
230
|
+
end
|
231
|
+
|
232
|
+
describe 'Array.ljust_rows!' do
|
233
|
+
before do
|
234
|
+
@array = [['a' , 'aa', 'a'],
|
235
|
+
['bbb', 'b' , 'b']]
|
236
|
+
@array2 = [['a' , 'aa'],
|
237
|
+
['bbb', 'b' ],
|
238
|
+
['c' , 'c' ]]
|
239
|
+
end
|
240
|
+
|
241
|
+
it 'basic' do
|
242
|
+
@array.ljust_rows!
|
243
|
+
@array.should == [['a ', 'aa', 'a ' ],
|
244
|
+
['bbb', 'b ', 'b ']]
|
245
|
+
end
|
246
|
+
|
247
|
+
it 'rotated' do
|
248
|
+
@array2.ljust_rows!
|
249
|
+
@array2.should == [['a ' , 'aa' ],
|
250
|
+
['bbb', 'b '],
|
251
|
+
['c' , 'c' ]]
|
252
|
+
end
|
253
|
+
|
254
|
+
it 'with non-string receiver array' do
|
255
|
+
@array = [[1, 1], [2, 22]]
|
256
|
+
@array.ljust_rows!
|
257
|
+
@array.should == [['1', '1'], ['2 ', '22']]
|
258
|
+
end
|
259
|
+
|
260
|
+
it 'with different padding character' do
|
261
|
+
@array.ljust_rows!('_')
|
262
|
+
@array.should == [['a_', 'aa', 'a_' ],
|
263
|
+
['bbb', 'b__', 'b__']]
|
264
|
+
end
|
265
|
+
end
|
266
|
+
|
267
|
+
describe 'Array.ljust_rows' do
|
268
|
+
before do
|
269
|
+
@array = [['a' , 'aa', 'a'],
|
270
|
+
['bbb', 'b' , 'b']]
|
271
|
+
end
|
272
|
+
|
273
|
+
it 'should not modify receiver array' do
|
274
|
+
@array.should == [['a' , 'aa' , 'a' ],
|
275
|
+
['bbb', 'b' , 'b' ]]
|
276
|
+
ret = @array.ljust_rows
|
277
|
+
ret.should == [['a ' , 'aa' , 'a ' ],
|
278
|
+
['bbb', 'b ', 'b ']]
|
279
|
+
# Should not have modified @array
|
280
|
+
@array.should == [['a' , 'aa', 'a'],
|
281
|
+
['bbb', 'b' , 'b']]
|
282
|
+
end
|
283
|
+
end
|
284
|
+
|
285
|
+
#---------------------------------------------------------------------------------------------------
|
286
|
+
|
287
|
+
describe 'Array.rjust_rows' do
|
288
|
+
before do
|
289
|
+
@array = [[ 'a', 'aa', 'a'],
|
290
|
+
['bbb', 'b', 'b']]
|
291
|
+
end
|
292
|
+
|
293
|
+
it 'should not modify receiver array' do
|
294
|
+
@array.should == [[ 'a', 'aa', 'a'],
|
295
|
+
['bbb', 'b', 'b']]
|
296
|
+
ret = @array.rjust_rows
|
297
|
+
ret.should == [[ ' a', 'aa', ' a'],
|
298
|
+
['bbb', ' b', ' b']]
|
299
|
+
# Should not have modified @array
|
300
|
+
@array.should == [[ 'a', 'aa', 'a'],
|
301
|
+
['bbb', 'b', 'b']]
|
302
|
+
end
|
303
|
+
end
|
304
|
+
=end
|
305
|
+
|
File without changes
|
@@ -0,0 +1,30 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2007 QualitySmith, Inc.
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes.
|
6
|
+
# Wait, so Facets has mode (http://facets.rubyforge.org/src/doc/rdoc/classes/Enumerable.html#M001253) but it doesn't have mean/average?
|
7
|
+
# Whether or not this Array#average is included, Facets ought to have an Enumerable#mean/average similar to mode that uses each iterator rather than Array#size. (Still might want to keep this version if it's more efficient for Arrays?)
|
8
|
+
#++
|
9
|
+
|
10
|
+
class Array
|
11
|
+
def sum
|
12
|
+
inject( nil ) { |sum,x| sum ? sum+x : x }
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
# _____ _
|
17
|
+
# |_ _|__ ___| |_
|
18
|
+
# | |/ _ \/ __| __|
|
19
|
+
# | | __/\__ \ |_
|
20
|
+
# |_|\___||___/\__|
|
21
|
+
#
|
22
|
+
=begin test
|
23
|
+
require 'test/unit'
|
24
|
+
|
25
|
+
class TheTest < Test::Unit::TestCase
|
26
|
+
def test_sum
|
27
|
+
assert_equal 5, [2, 3].sum
|
28
|
+
end
|
29
|
+
end
|
30
|
+
=end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
#--
|
2
|
+
# Author:: Tyler Rick
|
3
|
+
# Copyright:: Copyright (c) 2009, Tyler Rick
|
4
|
+
# License:: Ruby License
|
5
|
+
# Submit to Facets?:: Yes
|
6
|
+
# Developer notes::
|
7
|
+
# History::
|
8
|
+
#++
|
9
|
+
|
10
|
+
module Enumerable
|
11
|
+
def all_same?
|
12
|
+
all? {|a| a == first}
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
|
18
|
+
|
19
|
+
# _____ _
|
20
|
+
# |_ _|__ ___| |_
|
21
|
+
# | |/ _ \/ __| __|
|
22
|
+
# | | __/\__ \ |_
|
23
|
+
# |_|\___||___/\__|
|
24
|
+
#
|
25
|
+
=begin test
|
26
|
+
require 'spec/autorun'
|
27
|
+
|
28
|
+
describe 'Enumerable#all_same?' do
|
29
|
+
it 'works with arrays' do
|
30
|
+
[1, 2].all_same?.should == false
|
31
|
+
[1, 1].all_same?.should == true
|
32
|
+
|
33
|
+
(1 == '1').should == false
|
34
|
+
[1, '1'].all_same?.should == false
|
35
|
+
end
|
36
|
+
|
37
|
+
it 'works with Enumerators' do
|
38
|
+
'a b'.chars.all_same?.should == false
|
39
|
+
'aaa'.chars.all_same?.should == true
|
40
|
+
end
|
41
|
+
end
|
42
|
+
=end
|
43
|
+
|