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.
- 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
@@ -0,0 +1,18 @@
|
|
1
|
+
#* flex_array_forever.rb - Forever looping support for the flexible array class.
|
2
|
+
class FlexArray
|
3
|
+
#A helper class that encapsulates the idea of looping without end!
|
4
|
+
class ForEver
|
5
|
+
#Do something until false == true ;-)
|
6
|
+
def times(&block)
|
7
|
+
loop {block.call}
|
8
|
+
end
|
9
|
+
|
10
|
+
#Convert an eternity into an integer. ;-)
|
11
|
+
def to_i
|
12
|
+
nil
|
13
|
+
end
|
14
|
+
end
|
15
|
+
|
16
|
+
#Create a forever constant for use where infinite looping is needed.
|
17
|
+
FOREVER = ForEver.new
|
18
|
+
end
|
@@ -2,20 +2,20 @@
|
|
2
2
|
class FlexArray
|
3
3
|
#Retrieve the selected data from the \FlexArray.
|
4
4
|
#<br>Parameters
|
5
|
-
#* indexes - An array with as many entries as the flexible array has
|
5
|
+
#* indexes - An array with as many entries as the flexible array has
|
6
6
|
# dimensions. These entries may be an integer that is in the bounds of
|
7
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
|
8
|
+
# and end of the range are in the bounds of the range limit of that
|
9
9
|
# dimension, or it can be the symbol :all for all of the possible values
|
10
10
|
# of that dimension.
|
11
11
|
#<br>Returns
|
12
12
|
#* The data selected by the index or an array of data if the index selects
|
13
|
-
# more than one cell.
|
14
|
-
#<br>Note
|
13
|
+
# more than one cell.
|
14
|
+
#<br>Note
|
15
15
|
#* If the indexes parameter equals a single :all this maps to all
|
16
16
|
# elements of the array, regardless of its dimensionality.
|
17
17
|
def [](*indexes)
|
18
|
-
|
18
|
+
validate_index_count(indexes)
|
19
19
|
result = []
|
20
20
|
process_indexes(indexes) {|_index, posn| result << @array_data[posn]}
|
21
21
|
result.length == 1 ? result[0] : result
|
@@ -23,20 +23,22 @@ class FlexArray
|
|
23
23
|
|
24
24
|
#Store the value data into the \FlexArray.
|
25
25
|
#<br>Parameters
|
26
|
-
#* indexes - An array with as many entries as the flexible array has
|
26
|
+
#* indexes - An array with as many entries as the flexible array has
|
27
27
|
# dimensions. These entries may be an integer that is in the bounds of
|
28
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
|
29
|
+
# and end of the range are in the bounds of the range limit of that
|
30
30
|
# dimension, or it can be the symbol :all for all of the possible values
|
31
|
-
# of that dimension.
|
31
|
+
# of that dimension.
|
32
32
|
#* value - A value to be stored in the selected array entries.
|
33
33
|
#<br>Returns
|
34
34
|
#* The value stored in the array.
|
35
|
-
#<br>Note
|
35
|
+
#<br>Note
|
36
36
|
#* If the indexes parameter equals a single :all this maps to all
|
37
37
|
# elements of the array, regardless of its dimensionality.
|
38
38
|
def []=(*indexes, value)
|
39
|
-
|
40
|
-
|
39
|
+
validate_index_count(indexes)
|
40
|
+
source = value.in_array.cycle
|
41
|
+
process_indexes(indexes) {|_index, posn| @array_data[posn] = source.next}
|
42
|
+
value
|
41
43
|
end
|
42
44
|
end
|
@@ -2,34 +2,26 @@
|
|
2
2
|
class FlexArray
|
3
3
|
#Construct a flexible array object.
|
4
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
|
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
9
|
# integers to represent arrays of more than one dimension.
|
10
10
|
#* default - The optional default value. Defaults to nil.
|
11
11
|
#* init_block - An optional initialization block. The return values from this
|
12
12
|
# block are used to initialize the array. This overrides the default value.
|
13
13
|
#<br>Block Arguments
|
14
|
-
#* index - An array with one element per dimension with the fully qualified
|
14
|
+
#* index - An array with one element per dimension with the fully qualified
|
15
15
|
# index of the element being accessed. Note that the same array is passed
|
16
16
|
# in each time the block is called, so, if this parameter is to stored
|
17
17
|
# anywhere, it's best that it be cloned or duplicated first.
|
18
18
|
def initialize(array_specs, default=nil, &init_block)
|
19
|
-
@array_specs
|
20
|
-
|
21
|
-
#Parse the array limits.
|
22
|
-
array_specs.in_array.reverse_each do |spec|
|
23
|
-
@array_specs.insert(0, spec.to_spec_component(@count))
|
24
|
-
@count *= @array_specs[0].span
|
25
|
-
end
|
26
|
-
|
27
|
-
#Cache the dimensionality of the flex array.
|
28
|
-
@dimensions = @array_specs.length
|
19
|
+
@array_specs = SpecArray.new(array_specs.in_array)
|
20
|
+
@transposed = false
|
29
21
|
|
30
22
|
#Allocate the data for the array.
|
31
|
-
@array_data = Array.new(@
|
32
|
-
|
23
|
+
@array_data = Array.new(@array_specs.spec_count, default)
|
24
|
+
|
33
25
|
#Set up the array with the optional init_block.
|
34
26
|
if init_block
|
35
27
|
process_all {|index, posn| @array_data[posn] = init_block.call(index)}
|
@@ -39,6 +31,10 @@ class FlexArray
|
|
39
31
|
alias_method :shallow_dup, :dup
|
40
32
|
|
41
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.
|
42
38
|
def dup
|
43
39
|
other = self.shallow_dup
|
44
40
|
other.array_specs = @array_specs.dup
|
@@ -48,12 +44,12 @@ class FlexArray
|
|
48
44
|
|
49
45
|
#Construct a \FlexArray using other as a template or data source.
|
50
46
|
#<br>Parameters:
|
51
|
-
#* array_specs - The specification of the flex array subscript limits.
|
52
|
-
# These can either be integers, in which case the limits are 0...n or
|
53
|
-
# they can be ranges of integers, in which case the limits are those
|
54
|
-
# of the range, or they can be an array of integers and/or ranges of
|
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
|
55
51
|
# integers to represent arrays of more than one dimension.
|
56
|
-
#* other - The array or flex array that is the source of the data.
|
52
|
+
#* other - The array or flex array that is the source of the data.
|
57
53
|
#<br>Note:
|
58
54
|
#* To make a copy of a flex array, use dup instead.
|
59
55
|
def self.new_from(array_specs, other)
|
@@ -61,27 +57,27 @@ class FlexArray
|
|
61
57
|
FlexArray.new(array_specs) {iterator.next}
|
62
58
|
end
|
63
59
|
|
64
|
-
#Construct a \FlexArray using a all or a portion of portion of another
|
60
|
+
#Construct a \FlexArray using a all or a portion of portion of another
|
65
61
|
#\FlexArray as a data source.
|
66
62
|
#<br>Parameters
|
67
|
-
#* array_specs - The specification of the flex array subscript limits.
|
68
|
-
# These can either be integers, in which case the limits are 0...n or
|
69
|
-
# they can be ranges of integers, in which case the limits are those
|
70
|
-
# of the range, or they can be an array of integers and/or ranges of
|
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
|
71
67
|
# integers to represent arrays of more than one dimension.
|
72
|
-
#* other - The flex array source of the data used to build this flex
|
73
|
-
# array. If no limits or other_indexes are specified, the limits of the
|
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
|
74
70
|
# other array are used instead.
|
75
|
-
#* selection - The indexes of the required sub-set of data to use
|
71
|
+
#* selection - The indexes of the required sub-set of data to use
|
76
72
|
# in setting up the new array.
|
77
73
|
#<br>Notes:
|
78
|
-
#* If the entire source array is to be used, use new_from instead.
|
74
|
+
#* If the entire source array is to be used, use new_from instead.
|
79
75
|
#* To make a copy of a flex array, use dup instead.
|
80
76
|
def self.new_from_selection(array_specs, other, selection)
|
81
|
-
iterator = other.
|
77
|
+
iterator = other.select_cycle(selection)
|
82
78
|
FlexArray.new(array_specs) {iterator.next}
|
83
79
|
end
|
84
|
-
|
80
|
+
|
85
81
|
#Construct a \FlexArray as a duplicate of a source array or flex array.
|
86
82
|
#<br>Parameters
|
87
83
|
#* other - the array or flex array that is the source.
|
@@ -93,6 +89,6 @@ class FlexArray
|
|
93
89
|
result = FlexArray.new(0)
|
94
90
|
result.array_specs = other.array_specs.dup
|
95
91
|
result.array_data = other.array_data
|
96
|
-
result
|
92
|
+
result
|
97
93
|
end
|
98
94
|
end
|
@@ -4,27 +4,27 @@ class FlexArray
|
|
4
4
|
#Process a \FlexArray index array. This is the heart of the \FlexArray
|
5
5
|
#indexing process.
|
6
6
|
#<br>Parameters
|
7
|
-
#* indexes - An array with as many entries as the flexible array has
|
7
|
+
#* indexes - An array with as many entries as the flexible array has
|
8
8
|
# dimensions. See [] for more details. Note that since indexes is NOT
|
9
9
|
# a splat parameter, it must be passed as an array explicitly. If passed
|
10
10
|
# in as [:all] all elements of the array are processed.
|
11
11
|
#* block - a block to be called for each value selected by this process.
|
12
12
|
#<br>Block Arguments
|
13
|
-
#* current - An array with one element per dimension with the fully qualified
|
14
|
-
# index of the element being accessed.
|
13
|
+
#* current - An array with one element per dimension with the fully qualified
|
14
|
+
# index of the element being accessed.
|
15
15
|
#* posn - The position of the element being accessed in the data array.
|
16
16
|
def process_indexes(indexes, &block)
|
17
|
-
current = Array.new(
|
18
|
-
|
17
|
+
current = Array.new(dimensions, 0)
|
18
|
+
|
19
19
|
if indexes == [:all]
|
20
20
|
process_all_worker(0, 0, current, &block)
|
21
21
|
else
|
22
22
|
specs = @array_specs.each
|
23
|
-
|
23
|
+
|
24
24
|
checked = indexes.collect do |index|
|
25
25
|
index.to_index_range(specs.next)
|
26
26
|
end
|
27
|
-
|
27
|
+
|
28
28
|
process_indexes_worker(0, 0, checked, current, &block)
|
29
29
|
end
|
30
30
|
end
|
@@ -32,71 +32,76 @@ class FlexArray
|
|
32
32
|
#The worker bee for process_indexes.
|
33
33
|
#<br>Parameters
|
34
34
|
#* depth - The index of the dimension being processed.
|
35
|
-
#* posn - The partially computed position of the element being accessed
|
35
|
+
#* posn - The partially computed position of the element being accessed
|
36
36
|
# in the data array.
|
37
|
-
#* indexes - An array of array indexes. See the method [] for details on
|
37
|
+
#* indexes - An array of array indexes. See the method [] for details on
|
38
38
|
# what sorts of things these can be.
|
39
39
|
#* current - The partial fully qualified index of the element being accessed.
|
40
40
|
#* block - A block to be called for each value selected by this process.
|
41
41
|
#<br>Block Arguments
|
42
|
-
#* current - An array with one element per dimension with the fully qualified
|
43
|
-
# index of the element being accessed.
|
42
|
+
#* current - An array with one element per dimension with the fully qualified
|
43
|
+
# index of the element being accessed.
|
44
44
|
#* posn - The position of the element being accessed in the data array.
|
45
45
|
#<br>Note
|
46
46
|
#This is a recursive function. The recursion runs for index in 0..#dimensions
|
47
|
+
#<br>Endemic Code Smells
|
48
|
+
# :reek:LongParameterList
|
47
49
|
def process_indexes_worker(depth, posn, indexes, current, &block)
|
48
|
-
if depth ==
|
49
|
-
block.call(current, posn)
|
50
|
+
if depth == dimensions #Is there more work to do?
|
51
|
+
block.call(current, posn) #Index ready, call the block.
|
50
52
|
else
|
51
|
-
spec
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
53
|
+
spec = @array_specs[depth] #Get the current specification.
|
54
|
+
min, stride = spec.min, spec.stride #Extract the relevant info.
|
55
|
+
|
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.
|
59
|
+
process_indexes_worker(depth+1,
|
60
|
+
posn + (index-min) * stride,
|
61
|
+
indexes,
|
62
|
+
current,
|
63
|
+
&block)
|
60
64
|
end
|
61
65
|
end
|
62
66
|
end
|
63
|
-
|
67
|
+
|
64
68
|
#Special case where all of the array is being processed.
|
65
69
|
#<br>Parameters
|
66
70
|
#* block - A block to be called for each value selected by this process.
|
67
71
|
#<br>Block Arguments
|
68
|
-
#* current - An array with one element per dimension with the fully qualified
|
69
|
-
# index of the element being accessed.
|
72
|
+
#* current - An array with one element per dimension with the fully qualified
|
73
|
+
# index of the element being accessed.
|
70
74
|
#* posn - The position of the element being accessed in the data array.
|
71
75
|
def process_all(&block)
|
72
|
-
current = Array.new(
|
76
|
+
current = Array.new(dimensions, 0)
|
73
77
|
process_all_worker(0, 0, current, &block)
|
74
78
|
end
|
75
|
-
|
79
|
+
|
76
80
|
#The worker bee for process_all.
|
77
81
|
#<br>Parameters
|
78
82
|
#* depth - The index of the dimension being processed.
|
79
|
-
#* posn - The partially computed position of the element being accessed
|
83
|
+
#* posn - The partially computed position of the element being accessed
|
80
84
|
# in the data array.
|
81
85
|
#* current - The partial fully qualified index of the element being accessed.
|
82
86
|
#* block - A block to be called for each value selected by this process.
|
83
87
|
#<br>Block Arguments
|
84
|
-
#* current - An array with one element per dimension with the fully qualified
|
85
|
-
# index of the element being accessed.
|
88
|
+
#* current - An array with one element per dimension with the fully qualified
|
89
|
+
# index of the element being accessed.
|
86
90
|
#* posn - The position of the element being accessed in the data array.
|
87
91
|
#<br>Note
|
88
92
|
#This is a recursive function. The recursion runs for index in 0..#dimensions
|
89
93
|
def process_all_worker(depth, posn, current, &block)
|
90
|
-
if depth ==
|
91
|
-
block.call(current, posn)
|
94
|
+
if depth == dimensions #Is there more work to do?
|
95
|
+
block.call(current, posn) #Index ready, call the block.
|
92
96
|
else
|
93
|
-
spec
|
97
|
+
spec = @array_specs[depth] #Get the current specification.
|
94
98
|
stride = spec.stride
|
95
|
-
|
96
|
-
spec.each do |index|
|
97
|
-
current[depth] = index
|
99
|
+
|
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.
|
98
103
|
process_all_worker(depth+1, posn, current, &block)
|
99
|
-
posn += stride
|
104
|
+
posn += stride #Step to the next position.
|
100
105
|
end
|
101
106
|
end
|
102
107
|
end
|
@@ -1,12 +1,12 @@
|
|
1
1
|
#* flex_array_reshape.rb - The flexible array class reshape and related methods.
|
2
2
|
class FlexArray
|
3
|
-
#Return a copy of this \FlexArray, recast in a new shape, dropping or
|
3
|
+
#Return a copy of this \FlexArray, recast in a new shape, dropping or
|
4
4
|
#repeating data elements as required.
|
5
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
|
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
10
|
# integers to represent arrays of more than one dimension.
|
11
11
|
#<br>Returns
|
12
12
|
#* The reshaped flexible array.
|
@@ -15,31 +15,23 @@ class FlexArray
|
|
15
15
|
FlexArray.new(array_specs) {iterator.next}
|
16
16
|
end
|
17
17
|
|
18
|
-
#Recast this \FlexArray in a new shape, dropping or
|
18
|
+
#Recast this \FlexArray in a new shape, dropping or
|
19
19
|
#repeating data elements as required.
|
20
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
|
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
25
|
# integers to represent arrays of more than one dimension.
|
26
26
|
#<br>Returns
|
27
27
|
#* The reshaped, flexible array.
|
28
28
|
def reshape!(array_specs)
|
29
|
-
|
30
|
-
|
31
|
-
@array_specs, @array_data, @dimensions =
|
32
|
-
temp.array_specs, temp.array_data, temp.dimensions
|
29
|
+
temp = self.reshape(array_specs)
|
30
|
+
@array_specs, @array_data = temp.array_specs, temp.array_data
|
33
31
|
self
|
34
32
|
end
|
35
33
|
|
36
|
-
#
|
37
|
-
#a simple array.
|
38
|
-
def flatten
|
39
|
-
@array_data.flatten
|
40
|
-
end
|
41
|
-
|
42
|
-
#Convert the flex array to a simple array. Contained arrays are not affected.
|
34
|
+
#Convert the flex array to a simple array. Contained arrays are not affected.
|
43
35
|
def to_a
|
44
36
|
@array_data.dup
|
45
37
|
end
|
@@ -7,11 +7,24 @@ class FlexArray
|
|
7
7
|
#<br>Note
|
8
8
|
#* Transposing an array disables the speed-up for processing the array with
|
9
9
|
# an index of [:all].
|
10
|
-
def transpose(dim_a, dim_b)
|
10
|
+
def transpose!(dim_a, dim_b)
|
11
11
|
validate_dimension(dim_a)
|
12
12
|
validate_dimension(dim_b)
|
13
13
|
@array_specs[dim_a], @array_specs[dim_b] = @array_specs[dim_b], @array_specs[dim_a]
|
14
|
-
@transposed =
|
14
|
+
@transposed = @array_specs.transposed?
|
15
15
|
self
|
16
16
|
end
|
17
|
+
|
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].
|
26
|
+
def transpose(dim_a, dim_b)
|
27
|
+
FlexArray.new_from_array(self).transpose!(dim_a, dim_b)
|
28
|
+
end
|
29
|
+
|
17
30
|
end
|
@@ -7,31 +7,31 @@ class FlexArray
|
|
7
7
|
#* true if the arrays are compatible.
|
8
8
|
def compatible?(other)
|
9
9
|
@array_specs == other.array_specs
|
10
|
+
rescue Exception
|
11
|
+
false
|
10
12
|
end
|
11
13
|
|
12
14
|
private
|
13
|
-
|
15
|
+
|
14
16
|
#Validate the dimensionality of the indexes passed in.
|
15
17
|
#<br>Parameters
|
16
18
|
#* indexes - An array of indexes to be validated.
|
17
|
-
#<br>Returns
|
18
|
-
#* true if the indexes value is [:all] and the array is not transposed.
|
19
19
|
#<br>Exceptions
|
20
20
|
#* ArgumentError - raised on invalid dimensionality.
|
21
|
-
def
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
21
|
+
def validate_index_count(indexes)
|
22
|
+
unless indexes == [:all]
|
23
|
+
if dimensions != indexes.length
|
24
|
+
fail ArgumentError, "Incorrect number of indexes: #{dimensions} expected."
|
25
|
+
end
|
26
26
|
end
|
27
27
|
end
|
28
|
-
|
28
|
+
|
29
29
|
#Is this a valid dimension selector?
|
30
30
|
#<br>Exceptions
|
31
31
|
#* ArgumentError - raised on invalid dimension.
|
32
32
|
def validate_dimension(dim)
|
33
|
-
unless (0
|
34
|
-
fail ArgumentError, "Invalid
|
33
|
+
unless (0...dimensions) === dim
|
34
|
+
fail ArgumentError, "Invalid dimension selector: #{dim}"
|
35
35
|
end
|
36
36
|
end
|
37
37
|
end
|