Reputation: 2699
I have a reference to an big array, and some of the elements (from some index to the end) need to get used to insert new rows in a DB.
Is there anyway I can create a reference to part of a bigger array? Or another way I can use a part of a array with DBI's execute_array function, without having Perl copy loads of data in the background?
Here's what I want to do more efficiently:
$sh->execute_array({}, [ @{$arrayref}[@indexes] ]);
Upvotes: 6
Views: 4166
Reputation: 385754
$sh->execute_array({}, [ @{$arrayref}[@indexes] ]);
is similar to
sub new_array { my @a = @_; \@a }
$sh->execute_array({}, new_array( @{$arrayref}[@indexes] ));
Note the assignment which copies all the elements of the slice. We can avoid copying the scalars as follows:
sub array_of_aliases { \@_ }
$sh->execute_array({}, array_of_aliases( @{$arrayref}[@indexes] ));
Now, we're just copying pointers (SV*
) instead of entire scalars (and any string therein).
Upvotes: 4
Reputation: 57600
Array slices return multiple values and have the @
sigil:
my @array = (1, 2, 3, 4);
print join " ", @array[1..2]; # "2 3"
my $aref = [1, 2, 3, 4];
print join " ", @{$aref}[1..3]; # "2 3 4"
A slice will return a list (!= an array) of scalars. However, this is not a copy per se:
my @array = (1, 2, 3, 4);
for (@array[1..2]) {
s/\d/_/; # change the element of the array slice
}
print "@array"; # "1 _ _ 4"
So this is quite efficient.
If you want to create a new array (or an array reference), you have to copy the values:
my @array = (1, 2, 3, 4);
my @slice = @array[1..2];
my $slice = [ @array[1..2] ];
The syntax \@array[1..2]
would return a list of references to each element in the slice, but not a reference to the slice.
Upvotes: 6
Reputation: 4104
Parameter passing in Perl starts out as 'pass by reference'. If you want to know if a value copy is made, look to the source code.
In this case, the definition of execute_array
's second line copies the values referenced by @_
into a lexical named @array_of_arrays
.
On the bright side, it's a shallow copy. (at least as far as I've looked.)
Upvotes: 1