Мелкая копия ссылки в переменную в 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,

Другие вопросы по тегам