2013-04-06 2 views
7

В Perl, вы можете присвоить переменной ссылку на другой переменной, например:Shallow справочник копию в переменной Perl

my @array = (1..10); 
my $ref = \@array; 

И, как это ссылка, вы можете сделать что-то подобное и обе переменные будут затронуты:

push @array, 11; 
push @$ref, 12; 

и обе переменные будут содержать 1..12, потому что они указывают на один и тот же пространстве.

Теперь я хотел бы знать, есть ли способ, которым вы можете сделать то же самое, но начиная с ref и позже назначая эту ссылку простой переменной. Например:

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?

+1

Дубликата http://stackoverflow.com/questions/14070342/typeglob-aliases – 2013-04-06 12:10:23

+0

Принять к сведению записки Икегов о наиболее разумных подход. Если вы работаете с вложенными структурами Perl, достаточно, вы привыкли извлекать его как ref, а не копировать его в переменную массива. Он добавляет только 1-символьный тип к '$'. – Axeman

+0

@ Axeman2: Да, конечно. Этот вопрос был больше связан с воспитательным духом. :-) –

ответ

7

Четыре способа:

  • 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.



Вышеупомянутого Tie :: StdArrayX:

package Tie::StdArrayX; 
use Tie::Array qw(); 
our @ISA = 'Tie::StdArray'; 
sub TIEARRAY { bless $_[1] || [], $_[0] } 
5

Это можно сделать, когда массив является переменной пакета, используя typeglobs.

my $foo = [7,8,9]; 
our @bar; 
*bar = $foo; 
$foo->[1] = 3; 
print @bar;  # "739" 

лексические переменные (т.е. my @bar) не может быть назначены с типом-глобами, хотя. Возможно, есть лексическое решение или обходное решение, построенное вокруг PadWalker.

+2

Данные :: Псевдоним, а не PadWalker. – ikegami

Смежные вопросы