flex_array 0.2.0 → 0.3.0

Sign up to get free protection for your applications and to get access to all the features.
@@ -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
@@ -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
@@ -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.min, self.max, spec.max
31
-
32
- if self_min < 0 && self_max < 0
33
- alter_ego = (spec_max + self_min + 1)..(spec_max + self_max + 1)
34
- else
35
- alter_ego = self
36
- end
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
- lib/flex_array.rb -- 0 warnings
2
- lib/flex_array/array.rb -- 0 warnings
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/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..0, [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
-
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