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.
@@ -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