flex_array 0.3.2 → 0.3.7

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.
Files changed (48) hide show
  1. checksums.yaml +5 -5
  2. data/.gitignore +0 -15
  3. data/.reek.yml +17 -0
  4. data/CODE_OF_CONDUCT.md +49 -0
  5. data/README.md +67 -0
  6. data/bench/benchmark.rb +243 -0
  7. data/bench/results.txt +97 -0
  8. data/flex_array.gemspec +6 -10
  9. data/irbt.rb +18 -0
  10. data/lib/flex_array.rb +13 -30
  11. data/lib/flex_array/array.rb +9 -24
  12. data/lib/flex_array/flex_array_append.rb +4 -23
  13. data/lib/flex_array/flex_array_each.rb +33 -208
  14. data/lib/flex_array/flex_array_forever.rb +6 -4
  15. data/lib/flex_array/flex_array_index.rb +4 -29
  16. data/lib/flex_array/flex_array_new.rb +9 -56
  17. data/lib/flex_array/flex_array_process.rb +23 -63
  18. data/lib/flex_array/flex_array_reshape.rb +13 -23
  19. data/lib/flex_array/flex_array_transpose.rb +7 -16
  20. data/lib/flex_array/flex_array_validate.rb +6 -15
  21. data/lib/flex_array/integer.rb +4 -13
  22. data/lib/flex_array/object.rb +4 -13
  23. data/lib/flex_array/range.rb +4 -13
  24. data/lib/flex_array/spec_array.rb +5 -9
  25. data/lib/flex_array/spec_component.rb +14 -22
  26. data/lib/flex_array/version.rb +1 -2
  27. data/rakefile.rb +1 -24
  28. data/reek.txt +9 -2
  29. data/tests/array_test.rb +0 -4
  30. data/tests/flex_array_append_test.rb +0 -23
  31. data/tests/flex_array_each_test.rb +483 -487
  32. data/tests/flex_array_index_test.rb +0 -4
  33. data/tests/flex_array_new_test.rb +0 -4
  34. data/tests/flex_array_reshape_test.rb +4 -4
  35. data/tests/flex_array_test.rb +0 -4
  36. data/tests/flex_array_transpose_test.rb +0 -4
  37. data/tests/flex_array_validate_test.rb +5 -4
  38. data/tests/integer_test.rb +0 -4
  39. data/tests/object_test.rb +0 -4
  40. data/tests/range_test.rb +0 -4
  41. data/tests/spec_array_test.rb +0 -4
  42. data/tests/spec_component_test.rb +0 -4
  43. metadata +19 -49
  44. data/docs/Flex_Array_UG.odt +0 -0
  45. data/docs/Flex_Array_UG_Version_0_3_0.pdf +0 -0
  46. data/flex_array.reek +0 -109
  47. data/readme.txt +0 -2
  48. data/sire.rb +0 -82
@@ -1,13 +1,15 @@
1
- #* flex_array_forever.rb - Forever looping support for the flexible array class.
1
+ # Forever looping support for the flexible array class.
2
+
2
3
  class FlexArray
3
- #A helper class that encapsulates the idea of looping without end!
4
+ # A helper class that encapsulates the idea of looping without end!
5
+
4
6
  class ForEver
5
- #Do something until false == true ;-)
7
+ # Do something until false == true ;-)
6
8
  def times(&block)
7
9
  loop {block.call}
8
10
  end
9
11
 
10
- #Convert an eternity into an integer. ;-)
12
+ # Convert an eternity into an integer. ;-)
11
13
  def to_i
12
14
  nil
13
15
  end
@@ -1,19 +1,7 @@
1
- #* flex_array_index.rb - The flexible array indexing and related methods.
1
+ # The flexible array indexing and related methods.
2
+
2
3
  class FlexArray
3
- #Retrieve the selected data from the \FlexArray.
4
- #<br>Parameters
5
- #* indexes - An array with as many entries as the flexible array has
6
- # dimensions. These entries may be an integer that is in the bounds of
7
- # the range limit of that dimension, or it can be a range where the start
8
- # and end of the range are in the bounds of the range limit of that
9
- # dimension, or it can be the symbol :all for all of the possible values
10
- # of that dimension.
11
- #<br>Returns
12
- #* The data selected by the index or an array of data if the index selects
13
- # more than one cell.
14
- #<br>Note
15
- #* If the indexes parameter equals a single :all this maps to all
16
- # elements of the array, regardless of its dimensionality.
4
+ # Retrieve the selected data from the flex array.
17
5
  def [](*indexes)
18
6
  validate_index_count(indexes)
19
7
  result = []
@@ -21,20 +9,7 @@ class FlexArray
21
9
  result.length == 1 ? result[0] : result
22
10
  end
23
11
 
24
- #Store the value data into the \FlexArray.
25
- #<br>Parameters
26
- #* indexes - An array with as many entries as the flexible array has
27
- # dimensions. These entries may be an integer that is in the bounds of
28
- # the range limit of that dimension, or it can be a range where the start
29
- # and end of the range are in the bounds of the range limit of that
30
- # dimension, or it can be the symbol :all for all of the possible values
31
- # of that dimension.
32
- #* value - A value to be stored in the selected array entries.
33
- #<br>Returns
34
- #* The value stored in the array.
35
- #<br>Note
36
- #* If the indexes parameter equals a single :all this maps to all
37
- # elements of the array, regardless of its dimensionality.
12
+ # Store the value data into the flex array.
38
13
  def []=(*indexes, value)
39
14
  validate_index_count(indexes)
40
15
  source = value.in_array.cycle
@@ -1,28 +1,14 @@
1
- #* flex_array_new.rb - The flexible array class constructor and related methods.
1
+ # The flexible array class constructor and related methods.
2
2
  class FlexArray
3
- #Construct a flexible array object.
4
- #<br>Parameters
5
- #* array_specs - The specification of the flex array subscript limits.
6
- # These can either be integers, in which case the limits are 0...n or
7
- # they can be ranges of integers, in which case the limits are those
8
- # of the range, or they can be an array of integers and/or ranges of
9
- # integers to represent arrays of more than one dimension.
10
- #* default - The optional default value. Defaults to nil.
11
- #* init_block - An optional initialization block. The return values from this
12
- # block are used to initialize the array. This overrides the default value.
13
- #<br>Block Arguments
14
- #* index - An array with one element per dimension with the fully qualified
15
- # index of the element being accessed. Note that the same array is passed
16
- # in each time the block is called, so, if this parameter is to stored
17
- # anywhere, it's best that it be cloned or duplicated first.
3
+ # Construct a flexible array object.
18
4
  def initialize(array_specs, default=nil, &init_block)
19
5
  @array_specs = SpecArray.new(array_specs.in_array)
20
6
  @transposed = false
21
7
 
22
- #Allocate the data for the array.
8
+ # Allocate the data for the array.
23
9
  @array_data = Array.new(@array_specs.spec_count, default)
24
10
 
25
- #Set up the array with the optional init_block.
11
+ # Set up the array with the optional init_block.
26
12
  if init_block
27
13
  process_all {|index, posn| @array_data[posn] = init_block.call(index)}
28
14
  end
@@ -30,11 +16,7 @@ class FlexArray
30
16
 
31
17
  alias_method :shallow_dup, :dup
32
18
 
33
- #Create a duplicate of this array.
34
- #<br>Warning
35
- #* The rdoc tool messes this up. shallow_dup is NOT an alias for this
36
- # dup, but rather the original system implementation of dup. This dup,
37
- # overrides the default dup and calls shallow_dup as part of its processing.
19
+ # Create a duplicate of this array.
38
20
  def dup
39
21
  other = self.shallow_dup
40
22
  other.array_specs = @array_specs.dup
@@ -42,49 +24,20 @@ class FlexArray
42
24
  other
43
25
  end
44
26
 
45
- #Construct a \FlexArray using other as a template or data source.
46
- #<br>Parameters:
47
- #* array_specs - The specification of the flex array subscript limits.
48
- # These can either be integers, in which case the limits are 0...n or
49
- # they can be ranges of integers, in which case the limits are those
50
- # of the range, or they can be an array of integers and/or ranges of
51
- # integers to represent arrays of more than one dimension.
52
- #* other - The array or flex array that is the source of the data.
53
- #<br>Note:
54
- #* To make a copy of a flex array, use dup instead.
27
+ # Construct a flex array using other as a template or data source.
55
28
  def self.new_from(array_specs, other)
56
29
  iterator = other.array_data.cycle
57
30
  FlexArray.new(array_specs) {iterator.next}
58
31
  end
59
32
 
60
- #Construct a \FlexArray using a all or a portion of portion of another
61
- #\FlexArray as a data source.
62
- #<br>Parameters
63
- #* array_specs - The specification of the flex array subscript limits.
64
- # These can either be integers, in which case the limits are 0...n or
65
- # they can be ranges of integers, in which case the limits are those
66
- # of the range, or they can be an array of integers and/or ranges of
67
- # integers to represent arrays of more than one dimension.
68
- #* other - The flex array source of the data used to build this flex
69
- # array. If no limits or other_indexes are specified, the limits of the
70
- # other array are used instead.
71
- #* selection - The indexes of the required sub-set of data to use
72
- # in setting up the new array.
73
- #<br>Notes:
74
- #* If the entire source array is to be used, use new_from instead.
75
- #* To make a copy of a flex array, use dup instead.
33
+ # Construct a flex array using a all or a portion of portion of another flex
34
+ # array as a data source.
76
35
  def self.new_from_selection(array_specs, other, selection)
77
36
  iterator = other.select_cycle(selection)
78
37
  FlexArray.new(array_specs) {iterator.next}
79
38
  end
80
39
 
81
- #Construct a \FlexArray as a duplicate of a source array or flex array.
82
- #<br>Parameters
83
- #* other - the array or flex array that is the source.
84
- #<br>Returns
85
- #* A flex array.
86
- #<br>Note
87
- #* The data array of the new flex array is a reference to the source array.
40
+ # Construct a flex array as a duplicate of a source array or flex array.
88
41
  def self.new_from_array(other)
89
42
  result = FlexArray.new(0)
90
43
  result.array_specs = other.array_specs.dup
@@ -1,18 +1,9 @@
1
- #* flex_array_process.rb - The flexible array class index processing routines.
1
+ # The flexible array class index processing routines.
2
2
  class FlexArray
3
3
  private
4
- #Process a \FlexArray index array. This is the heart of the \FlexArray
5
- #indexing process.
6
- #<br>Parameters
7
- #* indexes - An array with as many entries as the flexible array has
8
- # dimensions. See [] for more details. Note that since indexes is NOT
9
- # a splat parameter, it must be passed as an array explicitly. If passed
10
- # in as [:all] all elements of the array are processed.
11
- #* block - a block to be called for each value selected by this process.
12
- #<br>Block Arguments
13
- #* current - An array with one element per dimension with the fully qualified
14
- # index of the element being accessed.
15
- #* posn - The position of the element being accessed in the data array.
4
+
5
+ # Process a flex array index array. This is the heart of the flex array
6
+ # indexing process.
16
7
  def process_indexes(indexes, &block)
17
8
  current = Array.new(dimensions, 0)
18
9
 
@@ -29,33 +20,19 @@ class FlexArray
29
20
  end
30
21
  end
31
22
 
32
- #The worker bee for process_indexes.
33
- #<br>Parameters
34
- #* depth - The index of the dimension being processed.
35
- #* posn - The partially computed position of the element being accessed
36
- # in the data array.
37
- #* indexes - An array of array indexes. See the method [] for details on
38
- # what sorts of things these can be.
39
- #* current - The partial fully qualified index of the element being accessed.
40
- #* block - A block to be called for each value selected by this process.
41
- #<br>Block Arguments
42
- #* current - An array with one element per dimension with the fully qualified
43
- # index of the element being accessed.
44
- #* posn - The position of the element being accessed in the data array.
45
- #<br>Note
46
- #This is a recursive function. The recursion runs for index in 0..#dimensions
47
- #<br>Endemic Code Smells
23
+ # The worker bee for process_indexes.
48
24
  # :reek:LongParameterList
49
25
  def process_indexes_worker(depth, posn, indexes, current, &block)
50
- if depth == dimensions #Is there more work to do?
51
- block.call(current, posn) #Index ready, call the block.
26
+ if depth == dimensions # Is there more work to do?
27
+ block.call(current, posn) # Index ready, call the block.
52
28
  else
53
- spec = @array_specs[depth] #Get the current specification.
54
- min, stride = spec.min, spec.stride #Extract the relevant info.
29
+ spec = @array_specs[depth] # Get the current specification.
30
+ min, stride = spec.min, spec.stride # Extract the relevant info.
31
+
32
+ indexes[depth].each do |index| # Iterate over the range.
33
+ current[depth] = index # Update the current index.
55
34
 
56
- indexes[depth].each do |index| #Iterate over the range.
57
- current[depth] = index #Update the current index.
58
- #Process the next component in the array index.
35
+ # Process the next component in the array index.
59
36
  process_indexes_worker(depth+1,
60
37
  posn + (index-min) * stride,
61
38
  indexes,
@@ -65,43 +42,26 @@ class FlexArray
65
42
  end
66
43
  end
67
44
 
68
- #Special case where all of the array is being processed.
69
- #<br>Parameters
70
- #* block - A block to be called for each value selected by this process.
71
- #<br>Block Arguments
72
- #* current - An array with one element per dimension with the fully qualified
73
- # index of the element being accessed.
74
- #* posn - The position of the element being accessed in the data array.
45
+ # Special case where all of the array is being processed.
75
46
  def process_all(&block)
76
47
  current = Array.new(dimensions, 0)
77
48
  process_all_worker(0, 0, current, &block)
78
49
  end
79
50
 
80
- #The worker bee for process_all.
81
- #<br>Parameters
82
- #* depth - The index of the dimension being processed.
83
- #* posn - The partially computed position of the element being accessed
84
- # in the data array.
85
- #* current - The partial fully qualified index of the element being accessed.
86
- #* block - A block to be called for each value selected by this process.
87
- #<br>Block Arguments
88
- #* current - An array with one element per dimension with the fully qualified
89
- # index of the element being accessed.
90
- #* posn - The position of the element being accessed in the data array.
91
- #<br>Note
92
- #This is a recursive function. The recursion runs for index in 0..#dimensions
51
+ # The worker bee for process_all.
93
52
  def process_all_worker(depth, posn, current, &block)
94
- if depth == dimensions #Is there more work to do?
95
- block.call(current, posn) #Index ready, call the block.
53
+ if depth == dimensions # Is there more work to do?
54
+ block.call(current, posn) # Index ready, call the block.
96
55
  else
97
- spec = @array_specs[depth] #Get the current specification.
56
+ spec = @array_specs[depth] # Get the current specification.
98
57
  stride = spec.stride
99
58
 
100
- spec.each do |index| #Iterate over the range.
101
- current[depth] = index #Update the current index.
102
- #Process the next component in the array specification.
59
+ spec.each do |index| # Iterate over the range.
60
+ current[depth] = index # Update the current index.
61
+
62
+ # Process the next component in the array specification.
103
63
  process_all_worker(depth+1, posn, current, &block)
104
- posn += stride #Step to the next position.
64
+ posn += stride # Step to the next position.
105
65
  end
106
66
  end
107
67
  end
@@ -1,38 +1,28 @@
1
- #* flex_array_reshape.rb - The flexible array class reshape and related methods.
1
+ # The flexible array class reshape and related methods.
2
+
2
3
  class FlexArray
3
- #Return a copy of this \FlexArray, recast in a new shape, dropping or
4
- #repeating data elements as required.
5
- #<br>Parameters
6
- #* array_specs - The specification of the flex array subscript limits.
7
- # These can either be integers, in which case the limits are 0...n or
8
- # they can be ranges of integers, in which case the limits are those
9
- # of the range, or they can be an array of integers and/or ranges of
10
- # integers to represent arrays of more than one dimension.
11
- #<br>Returns
12
- #* The reshaped flexible array.
4
+ # Return a copy of this flex array, recast in a new shape, dropping or
5
+ # repeating data elements as required.
13
6
  def reshape(array_specs)
14
7
  iterator = @array_data.cycle
15
8
  FlexArray.new(array_specs) {iterator.next}
16
9
  end
17
10
 
18
- #Recast this \FlexArray in a new shape, dropping or
19
- #repeating data elements as required.
20
- #<br>Parameters
21
- #* array_specs - The specification of the flex array subscript limits.
22
- # These can either be integers, in which case the limits are 0...n or
23
- # they can be ranges of integers, in which case the limits are those
24
- # of the range, or they can be an array of integers and/or ranges of
25
- # integers to represent arrays of more than one dimension.
26
- #<br>Returns
27
- #* The reshaped, flexible array.
11
+ # Recast this flex array in a new shape, dropping or repeating data elements
12
+ # as required.
28
13
  def reshape!(array_specs)
29
14
  temp = self.reshape(array_specs)
30
15
  @array_specs, @array_data = temp.array_specs, temp.array_data
31
16
  self
32
17
  end
33
18
 
34
- #Convert the flex array to a simple array. Contained arrays are not affected.
19
+ # Convert the flex array to a simple array. Contained arrays are not affected.
35
20
  def to_a
36
- @array_data.dup
21
+ if @transposed
22
+ fetch = self.cycle
23
+ Array.new(@array_data.length) { fetch.next }
24
+ else
25
+ @array_data.dup
26
+ end
37
27
  end
38
28
  end
@@ -1,12 +1,8 @@
1
- #* flex_array_transpose.rb - The flexible array class transpose and related methods.
1
+ # The flexible array class transpose and related methods.
2
+
2
3
  class FlexArray
3
- #Transpose the specified dimensions. This may change the "shape" of the array
4
- #if the transposed dimensions were of different limits.
5
- #<br>Returns
6
- #* The flex array transposed.
7
- #<br>Note
8
- #* Transposing an array disables the speed-up for processing the array with
9
- # an index of [:all].
4
+ # Transpose the specified dimensions. This may change the "shape" of the array
5
+ # if the transposed dimensions were of different limits.
10
6
  def transpose!(dim_a, dim_b)
11
7
  validate_dimension(dim_a)
12
8
  validate_dimension(dim_b)
@@ -15,14 +11,9 @@ class FlexArray
15
11
  self
16
12
  end
17
13
 
18
- #Return a reference to this array's data with the specified dimensions
19
- #transposed. This may change the "shape" of the array if the transposed
20
- #dimensions were of different limits.
21
- #<br>Returns
22
- #* The flex array transposed.
23
- #<br>Note
24
- #* Transposing an array disables the speed-up for processing the array with
25
- # an index of [:all].
14
+ # Return a reference to this array's data with the specified dimensions
15
+ # transposed. This may change the "shape" of the array if the transposed
16
+ # dimensions were of different limits.
26
17
  def transpose(dim_a, dim_b)
27
18
  FlexArray.new_from_array(self).transpose!(dim_a, dim_b)
28
19
  end
@@ -1,23 +1,16 @@
1
- #* flex_array_validate.rb - The flexible array class index validation routines.
1
+ # Some flexible array class index validation routines.
2
+
2
3
  class FlexArray
3
- #Is this array compatible with other?
4
- #<br>Parameters
5
- #* other - The object being tested for compatibility.
6
- #<br>Returns
7
- #* true if the arrays are compatible.
4
+ # Is this array compatible with other?
8
5
  def compatible?(other)
9
6
  @array_specs == other.array_specs
10
- rescue Exception
7
+ rescue
11
8
  false
12
9
  end
13
10
 
14
11
  private
15
12
 
16
- #Validate the dimensionality of the indexes passed in.
17
- #<br>Parameters
18
- #* indexes - An array of indexes to be validated.
19
- #<br>Exceptions
20
- #* ArgumentError - raised on invalid dimensionality.
13
+ # Validate the dimensionality of the indexes passed in.
21
14
  def validate_index_count(indexes)
22
15
  unless indexes == [:all]
23
16
  if dimensions != indexes.length
@@ -26,9 +19,7 @@ class FlexArray
26
19
  end
27
20
  end
28
21
 
29
- #Is this a valid dimension selector?
30
- #<br>Exceptions
31
- #* ArgumentError - raised on invalid dimension.
22
+ # Is this a valid dimension selector?
32
23
  def validate_dimension(dim)
33
24
  unless (0...dimensions) === dim
34
25
  fail ArgumentError, "Invalid dimension selector: #{dim}"
@@ -1,10 +1,7 @@
1
- #Extensions to Integer needed to support flex array.
1
+ # Extensions to Integer needed to support flex array.
2
+
2
3
  class Integer
3
- #Convert this integer to a limits component.
4
- #<br>Parameters
5
- #* stride - the number of cells separating data with adjacent indexes.
6
- #<br>Returns
7
- #* A SpecComponent object of 0...self
4
+ # Convert this integer to a limits component.
8
5
  def to_spec_component(stride)
9
6
  if self >= 0
10
7
  SpecComponent.new(0...self, stride)
@@ -13,13 +10,7 @@ class Integer
13
10
  end
14
11
  end
15
12
 
16
- #Convert this integer to an range index against the spec.
17
- #<br>Parameters
18
- #* spec - The spec component used to validate this index.
19
- #<br>Returns
20
- #* A range.
21
- #<br>Exceptions
22
- #* IndexError if the range is not valid.
13
+ # Convert this integer to a range index against the spec.
23
14
  def to_index_range(spec)
24
15
  alter_ego = (self >= 0) ? self : (spec.max + self + 1)
25
16
 
@@ -1,21 +1,12 @@
1
- #Extensions to Object needed to support flex array.
1
+ # Extensions to Object needed to support flex array.
2
+
2
3
  class Object
3
- #Fail with message since the array dimension is invalid.
4
- #<br>Parameters
5
- #* _stride - unused, required to maintain signature.
6
- #<br>Returns
7
- #* Nothing, always fails.
4
+ # Fail with message since the array dimension is invalid.
8
5
  def to_spec_component(_stride)
9
6
  fail ArgumentError, "Invalid flex array dimension: #{self.inspect}"
10
7
  end
11
8
 
12
- #Convert this object to an range index against the spec.
13
- #<br>Parameters
14
- #* spec - The spec component used to validate this index.
15
- #<br>Returns
16
- #* A range.
17
- #<br>Exceptions
18
- #* IndexError if the range is not valid.
9
+ # Convert this object to an range index against the spec.
19
10
  def to_index_range(spec)
20
11
  if self == :all
21
12
  spec.range