in reply to Array Slice Referencing
In a nutshell, Perl does not have a mechanism for taking a reference to a slice of an existing array. (Actually, it seems it does, though you won't find it documented anywhere to my knowledge. See below).
A slice is just a list of values; copies of the values from whichever datastructure they were drawn. They are no longer associated with that originating data structure. As soon as you 'take a slice of an array', you have copied the values into new memory--a list--and all association with the original array is lost.
Once you've taken the slice, you have a list (and the new memory allocated to hold it), and you cannot take a reference to a list. You can assign it to a new array and take a reference to that. Whether a formally named new array and a standard reference to that, or indirectly by assigning the list to an annonymous array which gives you that reference directly.
That said, there is a way to do what you are trying to do, though it is not formally described (other than in this old post by Juerd) and will doubtless be frowned upon as a nasty obscure hack. However, it utilises a standard and frequently used mechanism of Perl, and so far I have seen nothing to pursuade me that it is not a useful and valid tactic for certain kinds of operation.
#! perl -slw use strict; sub refSlice{ return \@_ } ## return a reference to an array of aliase +s! my @a = 1 .. 10; print "Original array:\n@a"; my $refSliceA = refSlice @a[ 2 .. 8 ]; print "\nsliceA:\n@$refSliceA"; my $refSliceB = refSlice @a[ 1, 3, 5, 7, 9 ]; print "\nsliceB:\n@$refSliceB"; $_ **= 2 for @$refSliceA; print "\nsliceA modified:\n@$refSliceA"; $_ /= 2 for @$refSliceB; print "\nsliceB modified:\n@$refSliceB"; print "\nArray after slice operations:\n@a"; __END__ C:\test>refslice.pl Original array: 1 2 3 4 5 6 7 8 9 10 sliceA: 3 4 5 6 7 8 9 sliceB: 2 4 6 8 10 sliceA modified: 9 16 25 36 49 64 81 sliceB modified: 1 8 18 32 5 Array after slice operations: 1 1 9 8 25 18 49 32 81 5
So, you can generate 'a reference to a slice of an array'. And you can hold multiple, slice references to an array. And mutating operations on those slices will mutate the original array.
However, that may not be as useful to you as you might hope, because this kind of 'slice reference' isn't a huge* total memory saver!
Update: It turns out (see below), that aliases are significantly lighter than copies or references. On the basis of purely experimental evidence, it seems that it costs 4 bytes per alias, rather than at least 12 bytes per copy. Well worth having in memory constrained situations.
The reference you obtain this way is actually a reference to an anonymous array of references*, to the scalars in the original array. And as reference to a scalar is itself a scalar, it takes almost as much memory to have a array of references as it does to have an array of copies of the scalars to which they point. Of course, references are fixed in size whereas the original scalars could hold large strings, in which case there may be some memory saving.
*Actually aliases, but that just semantics :)
It does however, allow you to perform operations on subsets, and multiple subsets and overlapping multiple subsets of an array without having to destroy the original ordering or having to try and re-create that original ordering by piecing the subsets back together.
For some applications where this is required, it is a very effective technique.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^2: Array Slice Referencing
by TimToady (Parson) on Jun 02, 2007 at 20:42 UTC | |
|
Re^2: Array Slice Referencing
by Jenda (Abbot) on Jun 02, 2007 at 21:52 UTC | |
by BrowserUk (Patriarch) on Jun 02, 2007 at 23:19 UTC |