quality_extensions 1.1.4 → 1.1.6
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/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
|
+
|