Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is [@{$myArray}] equivalent to $myArray in Perl if I'm not mutating the values?

Tags:

perl

I've got some Perl code:

{
  key => [@{$myArray}]
}

And I'd like to refactor that to:

{
  key => $myArray
}

Are the two semantically equivalent if I'm not mutating the value pointed to by key?

like image 259
aaronstacy Avatar asked Feb 17 '15 22:02

aaronstacy


2 Answers

They behave differently when

  1. @{ $h->{key} } is changed. (The difference you mentioned)

  2. @$array is changed.

  3. $array isn't dereferenceable as an array (e.g. $array is a string).

  4. $array is an object that overloads @{}.

  5. the elements of @$array are large or magical.

    The first snippet makes a copy of the elements when the hash is created, so it will be slower, and it will use more memory. Any magical aspects of the array or elements (e.g. if the array is a :shared array, or an array tied to Tie::File) will not be copied by the second snippet.

like image 191
ikegami Avatar answered Sep 29 '22 20:09

ikegami


No, they are not. Even if the array referenced by $data->{key} is never altered.

$myArray is a reference to the array. [@{$myArray}] makes a copy of the array referenced by $myArray and then takes a reference to that. Copying the array works both ways. It shields $myArray from changes made by $data but it also shields $data from changes in $myArray. Even if you don't mutate $data->{key} they still have semantic differences. For example...

my $myArray = ["a", "b", "c"];
$data->{key1} = $myArray;
$data->{key2} = [@{$myArray}];
$myArray->[1] = "q";

print $data->{key1}[1];  # q
print $data->{key2}[1];  # b

Unless you fully control $myArray and $data, that refactoring is unsafe.

like image 35
Schwern Avatar answered Sep 29 '22 20:09

Schwern