flex_array 0.2.0 → 0.3.0
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.
- checksums.yaml +8 -8
- data/lib/flex_array.rb +19 -13
- data/lib/flex_array/array.rb +19 -19
- data/lib/flex_array/flex_array_append.rb +11 -11
- data/lib/flex_array/flex_array_each.rb +390 -53
- data/lib/flex_array/flex_array_forever.rb +18 -0
- data/lib/flex_array/flex_array_index.rb +13 -11
- data/lib/flex_array/flex_array_new.rb +30 -34
- data/lib/flex_array/flex_array_process.rb +42 -37
- data/lib/flex_array/flex_array_reshape.rb +13 -21
- data/lib/flex_array/flex_array_transpose.rb +15 -2
- data/lib/flex_array/flex_array_validate.rb +11 -11
- data/lib/flex_array/integer.rb +2 -4
- data/lib/flex_array/object.rb +2 -4
- data/lib/flex_array/range.rb +10 -14
- data/lib/flex_array/spec_array.rb +47 -0
- data/lib/flex_array/spec_component.rb +11 -11
- data/rakefile.rb +22 -2
- data/reek.txt +2 -29
- data/tests/array_test.rb +19 -24
- data/tests/flex_array_append_test.rb +10 -10
- data/tests/flex_array_each_test.rb +466 -93
- data/tests/flex_array_index_test.rb +55 -57
- data/tests/flex_array_new_test.rb +21 -21
- data/tests/flex_array_reshape_test.rb +10 -17
- data/tests/flex_array_test.rb +20 -12
- data/tests/flex_array_transpose_test.rb +33 -6
- data/tests/integer_test.rb +1 -1
- data/tests/object_test.rb +7 -7
- data/tests/range_test.rb +9 -8
- data/tests/spec_array_test.rb +26 -0
- data/tests/spec_component_test.rb +19 -16
- metadata +6 -2
data/lib/flex_array/integer.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'spec_component'
|
2
|
-
|
3
1
|
#Extensions to Integer needed to support flex array.
|
4
2
|
class Integer
|
5
3
|
#Convert this integer to a limits component.
|
@@ -14,7 +12,7 @@ class Integer
|
|
14
12
|
fail ArgumentError, "Invalid flex array dimension: #{self.inspect}"
|
15
13
|
end
|
16
14
|
end
|
17
|
-
|
15
|
+
|
18
16
|
#Convert this integer to an range index against the spec.
|
19
17
|
#<br>Parameters
|
20
18
|
#* spec - The spec component used to validate this index.
|
@@ -24,7 +22,7 @@ class Integer
|
|
24
22
|
#* IndexError if the range is not valid.
|
25
23
|
def to_index_range(spec)
|
26
24
|
alter_ego = (self >= 0) ? self : (spec.max + self + 1)
|
27
|
-
|
25
|
+
|
28
26
|
if spec === alter_ego
|
29
27
|
alter_ego..alter_ego
|
30
28
|
else
|
data/lib/flex_array/object.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'spec_component'
|
2
|
-
|
3
1
|
#Extensions to Object needed to support flex array.
|
4
2
|
class Object
|
5
3
|
#Fail with message since the array dimension is invalid.
|
@@ -10,7 +8,7 @@ class Object
|
|
10
8
|
def to_spec_component(_stride)
|
11
9
|
fail ArgumentError, "Invalid flex array dimension: #{self.inspect}"
|
12
10
|
end
|
13
|
-
|
11
|
+
|
14
12
|
#Convert this object to an range index against the spec.
|
15
13
|
#<br>Parameters
|
16
14
|
#* spec - The spec component used to validate this index.
|
@@ -25,5 +23,5 @@ class Object
|
|
25
23
|
fail IndexError, "Invalid subscript: #{self.inspect}"
|
26
24
|
end
|
27
25
|
end
|
28
|
-
|
26
|
+
|
29
27
|
end
|
data/lib/flex_array/range.rb
CHANGED
@@ -1,5 +1,3 @@
|
|
1
|
-
require_relative 'spec_component'
|
2
|
-
|
3
1
|
#Extensions to Range needed to support flex array.
|
4
2
|
class Range
|
5
3
|
#Convert this integer to a limits component.
|
@@ -9,7 +7,7 @@ class Range
|
|
9
7
|
#* A SpecComponent object with the same range as self.
|
10
8
|
def to_spec_component(stride)
|
11
9
|
min = self.min
|
12
|
-
|
10
|
+
|
13
11
|
if self == (0...0)
|
14
12
|
SpecComponent.new(0...0, stride)
|
15
13
|
elsif !self.none? && min.is_a?(Integer) && (min >= 0) && self.max.is_a?(Integer)
|
@@ -18,7 +16,7 @@ class Range
|
|
18
16
|
fail ArgumentError, "Invalid flex array dimension: #{self.inspect}"
|
19
17
|
end
|
20
18
|
end
|
21
|
-
|
19
|
+
|
22
20
|
#Convert this range to an range index against the spec.
|
23
21
|
#<br>Parameters
|
24
22
|
#* spec - The spec component used to validate this index.
|
@@ -27,16 +25,14 @@ class Range
|
|
27
25
|
#<br>Exceptions
|
28
26
|
#* IndexError if the range is not valid.
|
29
27
|
def to_index_range(spec)
|
30
|
-
self_min, self_max, spec_max = self.
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
if spec === alter_ego.min && spec === alter_ego.max
|
39
|
-
alter_ego
|
28
|
+
self_min, self_max, spec_max = self.begin, self.end, spec.max
|
29
|
+
self_max -= 1 if self_max > 0 && self.exclude_end?
|
30
|
+
|
31
|
+
self_min = spec_max + self_min + 1 if self_min < 0
|
32
|
+
self_max = spec_max + self_max + 1 if self_max < 0
|
33
|
+
|
34
|
+
if spec === self_min && spec === self_max && self_min < self_max
|
35
|
+
self_min..self_max
|
40
36
|
else
|
41
37
|
fail IndexError, "Subscript out of range: #{self.inspect}"
|
42
38
|
end
|
@@ -0,0 +1,47 @@
|
|
1
|
+
#This helper class encapsulates an array of flex array spec components.
|
2
|
+
class SpecArray < Array
|
3
|
+
#The number of elements defined by this array specification.
|
4
|
+
attr_reader :spec_count
|
5
|
+
|
6
|
+
#The number of dimensions specified by this specification
|
7
|
+
alias spec_dimensions length
|
8
|
+
|
9
|
+
#Create a flex array specification.
|
10
|
+
#<br>Parameters
|
11
|
+
#* array_specs - The specification of the flex array subscript limits.
|
12
|
+
# These can either be an array of containing integers, in which case
|
13
|
+
# the limits are 0...n or they can be ranges, in which case the
|
14
|
+
# limits are those of the range.
|
15
|
+
def initialize(array_specs)
|
16
|
+
super(0)
|
17
|
+
@spec_count = 1
|
18
|
+
|
19
|
+
#Parse the array limits.
|
20
|
+
array_specs.reverse_each do |spec|
|
21
|
+
self.insert(0, spec.to_spec_component(@spec_count))
|
22
|
+
@spec_count *= self[0].span
|
23
|
+
end
|
24
|
+
|
25
|
+
self
|
26
|
+
end
|
27
|
+
|
28
|
+
#Is this array specification transposed in any way?
|
29
|
+
def transposed?
|
30
|
+
check = 1
|
31
|
+
|
32
|
+
self.reverse_each do |component|
|
33
|
+
return true unless check == component.stride
|
34
|
+
check *= component.span
|
35
|
+
end
|
36
|
+
|
37
|
+
false
|
38
|
+
end
|
39
|
+
|
40
|
+
#Enlarge the flex array along its first dimension.
|
41
|
+
def enlarge(growth)
|
42
|
+
self[0].enlarge(growth)
|
43
|
+
|
44
|
+
#Compute the new size.
|
45
|
+
@spec_count = self.inject(1) {|product, element| product*element.span}
|
46
|
+
end
|
47
|
+
end
|
@@ -2,11 +2,11 @@
|
|
2
2
|
class SpecComponent
|
3
3
|
#The range of acceptable values for this limit.
|
4
4
|
attr_reader :range
|
5
|
-
|
5
|
+
|
6
6
|
#The stride of this array dimension. That is, for each step in this
|
7
7
|
#dimension, how many steps are required in the low level array?
|
8
8
|
attr_reader :stride
|
9
|
-
|
9
|
+
|
10
10
|
#Create a limits component from its constituent data.
|
11
11
|
#<br>Parameters
|
12
12
|
#* range - the range of values for this index limit.
|
@@ -14,34 +14,34 @@ class SpecComponent
|
|
14
14
|
def initialize(range, stride)
|
15
15
|
@range, @stride = range, stride
|
16
16
|
end
|
17
|
-
|
17
|
+
|
18
18
|
#Forward '=== value' to the range.
|
19
19
|
def ===(value)
|
20
20
|
@range === value
|
21
21
|
end
|
22
|
-
|
22
|
+
|
23
23
|
#Limits are equal if their ranges are equal.
|
24
24
|
#<br>Returns
|
25
25
|
#* true if the spec components have equal ranges.
|
26
26
|
def ==(other)
|
27
27
|
@range == other.range
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
#Forward 'min' to the range.
|
31
31
|
def min
|
32
32
|
@range.min
|
33
33
|
end
|
34
|
-
|
34
|
+
|
35
35
|
#Forward 'max' to the range.
|
36
|
-
def max
|
36
|
+
def max
|
37
37
|
@range.max
|
38
38
|
end
|
39
|
-
|
39
|
+
|
40
40
|
#Forward 'each' and the block to the range.
|
41
41
|
def each(&block)
|
42
42
|
@range.each(&block)
|
43
43
|
end
|
44
|
-
|
44
|
+
|
45
45
|
#Compute the span of indexes in this limit component.
|
46
46
|
#<br>Returns
|
47
47
|
#* The span of the range or zero if there is none.
|
@@ -52,7 +52,7 @@ class SpecComponent
|
|
52
52
|
@range.max - @range.min + 1
|
53
53
|
end
|
54
54
|
end
|
55
|
-
|
55
|
+
|
56
56
|
#Enlarge the range of this spec by the growth term.
|
57
57
|
def enlarge(growth)
|
58
58
|
if @range.none?
|
@@ -61,7 +61,7 @@ class SpecComponent
|
|
61
61
|
@range = (@range.min)..(@range.max + growth)
|
62
62
|
end
|
63
63
|
end
|
64
|
-
|
64
|
+
|
65
65
|
#Compute the step required for the index value.
|
66
66
|
#<br>Returns
|
67
67
|
#* The number of array cells to be skipped for this index.
|
data/rakefile.rb
CHANGED
@@ -4,7 +4,7 @@ require 'rdoc/task'
|
|
4
4
|
|
5
5
|
RDoc::Task.new do |rdoc|
|
6
6
|
rdoc.rdoc_dir = "rdoc"
|
7
|
-
rdoc.rdoc_files = ["lib/flex_array.rb",
|
7
|
+
rdoc.rdoc_files = ["lib/flex_array.rb",
|
8
8
|
"lib/flex_array/flex_array_new.rb",
|
9
9
|
"lib/flex_array/flex_array_index.rb",
|
10
10
|
"lib/flex_array/flex_array_each.rb",
|
@@ -13,10 +13,12 @@ RDoc::Task.new do |rdoc|
|
|
13
13
|
"lib/flex_array/flex_array_transpose.rb",
|
14
14
|
"lib/flex_array/flex_array_process.rb",
|
15
15
|
"lib/flex_array/flex_array_validate.rb",
|
16
|
+
"lib/flex_array/flex_array_forever.rb",
|
16
17
|
"lib/flex_array/object.rb",
|
17
18
|
"lib/flex_array/integer.rb",
|
18
19
|
"lib/flex_array/range.rb",
|
19
20
|
"lib/flex_array/array.rb",
|
21
|
+
"lib/flex_array/spec_array.rb",
|
20
22
|
"lib/flex_array/spec_component.rb",
|
21
23
|
"license.txt", "README.txt"]
|
22
24
|
rdoc.options << '--visibility' << 'private'
|
@@ -24,6 +26,7 @@ end
|
|
24
26
|
|
25
27
|
Rake::TestTask.new do |t|
|
26
28
|
t.test_files = ["tests/spec_component_test.rb",
|
29
|
+
"tests/spec_array_test.rb",
|
27
30
|
"tests/object_test.rb",
|
28
31
|
"tests/integer_test.rb",
|
29
32
|
"tests/range_test.rb",
|
@@ -40,5 +43,22 @@ Rake::TestTask.new do |t|
|
|
40
43
|
end
|
41
44
|
|
42
45
|
task :reek do |t|
|
43
|
-
`reek lib > reek.txt`
|
46
|
+
`reek --no-color lib > reek.txt`
|
47
|
+
end
|
48
|
+
|
49
|
+
def eval_puts(str)
|
50
|
+
puts str
|
51
|
+
eval str
|
52
|
+
end
|
53
|
+
|
54
|
+
task :console do
|
55
|
+
require 'irb'
|
56
|
+
require 'irb/completion'
|
57
|
+
require_relative 'lib/flex_array'
|
58
|
+
eval_puts "@a = FlexArray.new([2,3,4]) {|i| i.clone}"
|
59
|
+
eval_puts "@b = FlexArray.new([2,3,4]) {|i| (i[0]+i[2])*(i[1] + i[2])}"
|
60
|
+
eval_puts "@c = FlexArray.new([0,3])"
|
61
|
+
eval_puts "@d = FlexArray.new([3,3]) {|i| i[0]*3 + i[1]}"
|
62
|
+
ARGV.clear
|
63
|
+
IRB.start
|
44
64
|
end
|
data/reek.txt
CHANGED
@@ -1,29 +1,2 @@
|
|
1
|
-
|
2
|
-
|
3
|
-
lib/flex_array/flex_array_append.rb -- 0 warnings
|
4
|
-
lib/flex_array/flex_array_each.rb -- 11 warnings:
|
5
|
-
[91, 94]:FlexArray#_each_raw calls process_indexes(indexes) twice (DuplicateMethodCall)
|
6
|
-
[94]:FlexArray#_each_raw contains iterators nested 2 deep (NestedIterators)
|
7
|
-
[41, 44]:FlexArray#cycle calls @array_data[posn] twice (DuplicateMethodCall)
|
8
|
-
[41, 44]:FlexArray#cycle calls process_indexes(indexes) twice (DuplicateMethodCall)
|
9
|
-
[44]:FlexArray#cycle contains iterators nested 3 deep (NestedIterators)
|
10
|
-
[18, 21]:FlexArray#each calls @array_data[posn] twice (DuplicateMethodCall)
|
11
|
-
[18, 21]:FlexArray#each calls process_indexes(indexes) twice (DuplicateMethodCall)
|
12
|
-
[21]:FlexArray#each contains iterators nested 2 deep (NestedIterators)
|
13
|
-
[65, 68]:FlexArray#each_with_index calls @array_data[posn] twice (DuplicateMethodCall)
|
14
|
-
[65, 68]:FlexArray#each_with_index calls process_indexes(indexes) twice (DuplicateMethodCall)
|
15
|
-
[68]:FlexArray#each_with_index contains iterators nested 2 deep (NestedIterators)
|
16
|
-
lib/flex_array/flex_array_index.rb -- 0 warnings
|
17
|
-
lib/flex_array/flex_array_new.rb -- 0 warnings
|
18
|
-
lib/flex_array/flex_array_process.rb -- 3 warnings:
|
19
|
-
[89]:FlexArray#process_all_worker has approx 7 statements (TooManyStatements)
|
20
|
-
[47]:FlexArray#process_indexes_worker has 4 parameters (LongParameterList)
|
21
|
-
[47]:FlexArray#process_indexes_worker has approx 9 statements (TooManyStatements)
|
22
|
-
lib/flex_array/flex_array_reshape.rb -- 0 warnings
|
23
|
-
lib/flex_array/flex_array_transpose.rb -- 0 warnings
|
24
|
-
lib/flex_array/flex_array_validate.rb -- 0 warnings
|
25
|
-
lib/flex_array/integer.rb -- 0 warnings
|
26
|
-
lib/flex_array/object.rb -- 0 warnings
|
27
|
-
lib/flex_array/range.rb -- 0 warnings
|
28
|
-
lib/flex_array/spec_component.rb -- 0 warnings
|
29
|
-
14 total warnings
|
1
|
+
|
2
|
+
0 total warnings
|
data/tests/array_test.rb
CHANGED
@@ -1,24 +1,24 @@
|
|
1
|
-
require_relative '../lib/flex_array
|
1
|
+
require_relative '../lib/flex_array'
|
2
2
|
require 'minitest/autorun'
|
3
3
|
|
4
4
|
class ArrayTester < MiniTest::Unit::TestCase
|
5
5
|
$do_this_only_one_time = "" unless defined? $do_this_only_one_time
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(*all)
|
8
8
|
if $do_this_only_one_time != __FILE__
|
9
9
|
puts
|
10
|
-
puts "Running test file: #{File.split(__FILE__)[1]}"
|
10
|
+
puts "Running test file: #{File.split(__FILE__)[1]}"
|
11
11
|
$do_this_only_one_time = __FILE__
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
super(*all)
|
15
15
|
end
|
16
16
|
|
17
17
|
def test_the_limits_method
|
18
18
|
test = [1,2,3,4,5,6]
|
19
|
-
assert_equal([0...6], test.limits)
|
19
|
+
assert_equal([0...6], test.limits)
|
20
20
|
end
|
21
|
-
|
21
|
+
|
22
22
|
def test_the_array_specs_method
|
23
23
|
test = [1,2,3,4,5,6].array_specs
|
24
24
|
assert_equal(1, test.length)
|
@@ -26,37 +26,32 @@ class ArrayTester < MiniTest::Unit::TestCase
|
|
26
26
|
assert_equal(0...6, test[0].range)
|
27
27
|
assert_equal(1, test[0].stride)
|
28
28
|
end
|
29
|
-
|
29
|
+
|
30
30
|
def test_the_array_data_method
|
31
31
|
test = [1,2,3,4,5,6]
|
32
32
|
assert_equal(test, test.array_data)
|
33
33
|
assert_equal(test.object_id, test.array_data.object_id)
|
34
34
|
end
|
35
|
-
|
35
|
+
|
36
36
|
def test_the_count_method
|
37
37
|
test = [1,2,3,4,5,6]
|
38
38
|
assert_equal(test.count, 6)
|
39
39
|
assert_equal(test.count, test.length)
|
40
40
|
end
|
41
|
-
|
41
|
+
|
42
42
|
def test_the_to_index_range_method
|
43
43
|
spec = SpecComponent.new(0...10, 1)
|
44
|
-
|
45
|
-
assert_equal(0
|
46
|
-
assert_equal(9
|
47
|
-
assert_equal(0
|
48
|
-
|
49
|
-
assert_equal(0
|
50
|
-
assert_equal(1
|
51
|
-
assert_equal(8
|
52
|
-
|
53
|
-
assert_raises(IndexError) { [0,9,0].to_index_range(spec) }
|
54
|
-
assert_raises(IndexError) { [9,0].to_index_range(spec) }
|
55
|
-
assert_raises(IndexError) { [-1,-2].to_index_range(spec) }
|
44
|
+
|
45
|
+
assert_equal([0], [0].to_index_range(spec))
|
46
|
+
assert_equal([9,9], [9,9].to_index_range(spec))
|
47
|
+
assert_equal([0,9], [0,9].to_index_range(spec))
|
48
|
+
|
49
|
+
assert_equal([0, 9], [0,-1].to_index_range(spec))
|
50
|
+
assert_equal([1, 8], [1,-2].to_index_range(spec))
|
51
|
+
assert_equal([8, 9], [-2,-1].to_index_range(spec))
|
52
|
+
|
56
53
|
assert_raises(IndexError) { [0,10].to_index_range(spec) }
|
57
|
-
|
58
|
-
assert_raises(TypeError) { [].to_index_range(spec) }
|
59
|
-
assert_raises(TypeError) { [0].to_index_range(spec) }
|
54
|
+
|
60
55
|
assert_raises(TypeError) { [:one, :two].to_index_range(spec) }
|
61
56
|
end
|
62
57
|
end
|
@@ -3,14 +3,14 @@ require 'minitest/autorun'
|
|
3
3
|
|
4
4
|
class FlexArrayAppendTester < MiniTest::Unit::TestCase
|
5
5
|
$do_this_only_one_time = "" unless defined? $do_this_only_one_time
|
6
|
-
|
6
|
+
|
7
7
|
def initialize(*all)
|
8
8
|
if $do_this_only_one_time != __FILE__
|
9
9
|
puts
|
10
|
-
puts "Running test file: #{File.split(__FILE__)[1]}"
|
10
|
+
puts "Running test file: #{File.split(__FILE__)[1]}"
|
11
11
|
$do_this_only_one_time = __FILE__
|
12
12
|
end
|
13
|
-
|
13
|
+
|
14
14
|
super(*all)
|
15
15
|
end
|
16
16
|
|
@@ -18,13 +18,13 @@ class FlexArrayAppendTester < MiniTest::Unit::TestCase
|
|
18
18
|
f = FlexArray.new([1,3], "Title")
|
19
19
|
assert_equal(2, f.dimensions)
|
20
20
|
assert_equal([0...1, 0...3], f.limits)
|
21
|
-
|
21
|
+
|
22
22
|
f << [1,2,3]
|
23
23
|
assert_equal(2, f.dimensions)
|
24
24
|
assert_equal([0..1, 0...3], f.limits)
|
25
25
|
a = ["Title","Title","Title",1,2,3]
|
26
26
|
assert_equal(a, f.array_data)
|
27
|
-
|
27
|
+
|
28
28
|
g = FlexArray.new_from_array([4,5,6])
|
29
29
|
f << g
|
30
30
|
assert_equal(2, f.dimensions)
|
@@ -37,7 +37,7 @@ class FlexArrayAppendTester < MiniTest::Unit::TestCase
|
|
37
37
|
f = FlexArray.new([0,3])
|
38
38
|
assert_equal(2, f.dimensions)
|
39
39
|
assert_equal([0...0, 0...3], f.limits)
|
40
|
-
|
40
|
+
|
41
41
|
f << [1,2,3]
|
42
42
|
assert_equal(2, f.dimensions)
|
43
43
|
assert_equal([0...1, 0...3], f.limits)
|
@@ -55,11 +55,11 @@ class FlexArrayAppendTester < MiniTest::Unit::TestCase
|
|
55
55
|
f = FlexArray.new([1,3], "Title")
|
56
56
|
assert_raises(ArgumentError) { f << [3,4] }
|
57
57
|
assert_raises(ArgumentError) { f << [1,2,3,4] }
|
58
|
-
|
58
|
+
|
59
59
|
g = FlexArray.new([1,2], "Title")
|
60
60
|
assert_raises(ArgumentError) { f << g }
|
61
61
|
end
|
62
|
-
|
62
|
+
|
63
63
|
def test_the_copy_data_method
|
64
64
|
f = FlexArray.new([2,3], "Title")
|
65
65
|
g = FlexArray.new([2,3], "Fight")
|
@@ -67,12 +67,12 @@ class FlexArrayAppendTester < MiniTest::Unit::TestCase
|
|
67
67
|
assert_equal(f.array_data, g.array_data)
|
68
68
|
assert(f.array_data.object_id != g.array_data.object_id)
|
69
69
|
end
|
70
|
-
|
70
|
+
|
71
71
|
def test_copy_data_method_failures
|
72
72
|
f = FlexArray.new([2,3], "Title")
|
73
73
|
g = FlexArray.new([2,4], "Fight")
|
74
74
|
assert_raises(ArgumentError) { f.copy_data(g) }
|
75
|
-
|
75
|
+
|
76
76
|
g = FlexArray.new([1,3], "Fight")
|
77
77
|
assert_raises(ArgumentError) { f.copy_data(g) }
|
78
78
|
|