Мелкая копия ссылки в переменную в Perl
В Perl вы можете присвоить переменной ссылку на другую переменную, например так:
my @array = (1..10);
my $ref = \@array;
И, как это ссылка, вы можете сделать что-то вроде этого, и обе переменные будут затронуты:
push @array, 11;
push @$ref, 12;
и обе переменные будут содержать 1..12
потому что они оба указывают на одно и то же пространство.
Теперь я хотел бы знать, есть ли способ сделать то же самое, но начиная с ссылки, а затем присваивая эту ссылку простой переменной. Например:
my $ref = [1..12];
my @array = # something here that makes @array point to the same space $ref contains
Я знаю, что могу просто назначить это так:
my @array = @$ref;
но это копия. Если я изменю $ref или @array, это будут независимые изменения.
Есть ли способ заставить @array указывать на ту же переменную, что и $ref?
2 ответа
Четыре способа:
our @array; local *array = $ref;
\my @array = $ref;
(Экспериментальная функция добавлена в 5.22)use Data::Alias; alias my @array = @$ref;
- Используя магию (например,
tie my @array, 'Tie::StdArrayX', $ref;
)
Но, конечно, разумный подход заключается в том, чтобы сделать
my $array = $ref;
и использовать @$array
вместо @array
,
Вышеупомянутая связь::StdArrayX:
package Tie::StdArrayX;
use Tie::Array qw( );
our @ISA = 'Tie::StdArray';
sub TIEARRAY { bless $_[1] || [], $_[0] }
Это можно сделать, когда массив является переменной пакета, используя typeglobs.
my $foo = [7,8,9];
our @bar;
*bar = $foo;
$foo->[1] = 3;
print @bar; # "739"
Лексические переменные (т.е. my @bar
) нельзя назначать с помощью typeglobs. Может быть, существует лексическое решение или обходной путь PadWalker
,