Jonathan Lang wrote:

Larry Wall wrote: > : If you want the last index, say '*[-1]' instead of '* - 1'. > : If you want the first index, say '*[0]' instead of '* + 0'. > > So the generic version of leaving off both ends would be *[1]..*[-2] > (ignoring that we'd probably write *[0]^..^*[-1] for that instead).## Advertising

Correct - although that assumes that the indices are consecutive (as opposed to, say, 1, 2, 4, 8, 16...); this version of * makes no such assumption.

Another thought: '*[1..-2]' or '*[0^..^-1]' would do the trick here - except for the fact that the Range 1..-2 doesn't normally make sense. Suggestion: when dealing with Ranges in unshaped arrays, negative endpoints are treated like negative indices (i.e., '$_ += [EMAIL PROTECTED]'). In effect, using * as an array of indices gives us the ordinals notation that has been requested on occasion: '*[0]' means 'first element', '*[1]' means 'second element', '*[-1]' means 'last element', '*[0..2]' means 'first three elements', and so on - and this works regardless of what the actual indices are.

Like I said, I tend to miss intricacies. For instance, I never considered what would be involved in applying a subscriptor to a multidimensional Whatever (e.g., what can you do with '**[...]'?). Part of that is that I'm not yet comfortable with multidimensional slices (or arrays, for that matter); when reading about them, I keep on getting the feeling that there's something going on here that the big boys know about that I don't - implicit assumptions, et al.

I think I've got a better grip on it now. Here's how I understand it to work: A multidimensional array is defined by providing a list of lists, each giving all of the valid indices along one axis (i.e., in one dimension). The overall shape of the array will be rectangular, or a higher-dimensional analog of rectangular. There may be gaps in the indices (in which case the array is a sparse array as well as a multidimensional array); but if there are, the gaps also conform to the rectangular structure: it's as if you carved a solid rectangle into two or more rectangular pieces and pulled them apart a bit. That is, @array[-1, +1; -1 +1] is effectively a 2x2 square array with valid x-indices of -1 and +1 and valid y-indices of -1 and +1. To access an element in a multidimensional array, use a semicolon-delimited list of indices in the square braces: '@cube[1;1;1]' will access the center element of a [^3;^3;^3] shaped array, while '@array[*;*;1]' will access a 3x3 horizontal slice of it. When putting together a list literal, things work a bit differently. Create a one-dimensional literal by means of a comma-delimited list of values; create a two-dimensional literal by means of a semicolon-delimited list of comma-delimited lists of values: 1, 2, 3 # one-dimensional list literal with a length of 3 (1, 2, 3; 4, 5, 6) # two-dimensional list literal with a length of 2 and a width of 3. (1; 2; 3) # two-dimensional list literal with a length of 3 and a width of 1. I would guess that you would build higher-dimensional "literals" by nesting parentheses-enclosed semicolon-delimited lists: (( 0, 1; 2, 3; 4, 5; 6, 7; 8, 9); (10, 11; 12, 13; 14, 15; 16, 17; 18, 19); (20, 21; 22, 23; 24, 25; 26, 27; 28, 29)) # three-dimensional list literal with a length of 3, a width of 5, and a height of 2. The outermost set of semicolons delimits the first dimension, and the commas delimit the last dimension. That is, semicolon-delimited lists nest, and comma-delimited lists flatten. Furthermore, the "list literal" gets assigned to the array by means of ordinal coordinates: my @cube[-1..+1; -1..+1; -1..+1] = ((1, 2, 3; 4, 5, 6; 7, 8, 9); (10, 11, 12; 13, 14, 15; 16, 17, 18); (19, 20, 21; 22, 23, 24; 25, 26, 27)); would be equivalent to my @cube[1..3; 1..3; 1..3]; @cube[**[0; **]] = (1, 2, 3; 4, 5, 6; 7, 8, 9); @cube[**[0; **]] = (10, 11, 12; 13, 14, 15; 16, 17, 18); @cube[**[0; **]] = (19, 20, 21; 22, 23, 24; 25, 26, 27); or my @cube[1..3; 1..3; 1..3]; @cube[**[0; 0; *]] = 1, 2, 3; @cube[**[0; 1; *]] = 4, 5, 6; @cube[**[0; 2; *]] = 7, 8, 9; @cube[**[1; 0; *]] = 10, 11, 12; @cube[**[1; 1; *]] = 13, 14, 15; @cube[**[1; 2; *]] = 16, 17, 18; @cube[**[2; 0; *]] = 19, 20, 21; @cube[**[2; 1; *]] = 22, 23, 24; @cube[**[2; 2; *]] = 25, 26, 27; or my @cube[1..3; 1..3; 1..3]; @cube[**[0; 0; 0]] = 1; @cube[**[0; 0; 1]] = 2; @cube[**[0; 0; 2]] = 3; @cube[**[0; 1; 0]] = 4; @cube[**[0; 1; 1]] = 5; @cube[**[0; 1; 2]] = 6; ... where say @cube[**[1; 1; 1]]; would be equivalent to say @cube[0; 0; 0]; Do I have the general idea? -- Jonathan "Dataweaver" Lang