7

In Perl, you can assign to a variable a reference to another variable, like this:

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

And, as it is a reference, you can do something like this and both variables will be affected:

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

and both variables will contain 1..12, because they both point to the same space.

Now, I'd like to know if there is any way you can do the same thing, but starting with a ref and later assigning that reference to a plain variable. For example:

my $ref = [1..12];
my @array = # something here that makes @array point to the same space $ref contains

I know I can just assign it like this:

my @array = @$ref;

but, that's a copy. If I alter $ref or @array, those will be independent changes.

Is there some way to make @array point to the same variable as $ref?

Francisco Zarabozo
  • 3,676
  • 2
  • 28
  • 54
  • 1
    Duplicate http://stackoverflow.com/questions/14070342/typeglob-aliases –  Apr 06 '13 at 12:10
  • Take note of Ikegami's note about the most sensible approach. If you work with nested Perl structures, enough, you'll get used to retrieving it as a ref, instead of copying it to an array variable. It only adds 1-character to type to `$`. – Axeman Apr 06 '13 at 14:20
  • @Axeman2: Yes, of course. This question was more on the educational spirit. :-) – Francisco Zarabozo Apr 06 '13 at 16:50

2 Answers2

7

Four ways:

  • our @array; local *array = $ref;
  • \my @array = $ref; (Experimental feature added to 5.22)
  • use Data::Alias; alias my @array = @$ref;
  • Using magic (e.g. tie my @array, 'Tie::StdArrayX', $ref;)

But of course, the sensible approach is to do

my $array = $ref;

and use @$array instead of @array.



Aforementioned Tie::StdArrayX:

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

This can be done when the array is a package variable, using typeglobs.

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

Lexical variables (i.e. my @bar) can't be assigned to with typeglobs, though. Maybe there is a lexical solution or workaround built around PadWalker.

mob
  • 117,087
  • 18
  • 149
  • 283