chris01
chris01

Reputation: 12331

Perl: scope and allocation of a named variable

Here is a little sample.

my %X = ();

for (my $i = 0; $i < 5; $i ++)
{
    $X {$i} = [$i .. 4];  # the assignment: reference to an unnamed array
}

# this is just for output - you can ignore it
foreach (sort keys %X)
{
    print "\n" . $_ . " = ";
    foreach (@{$X {$_}})
    {
        print $_;
    }
}

The output is like expected.

0 = 01234
1 = 1234
2 = 234
3 = 34
4 = 4

If I use a local variable for the assignment it will produce the same output - thats ok! The memory for the list is always reallocated and not overwritten because @l is always new. There is still a reference to it in %X so no release is possible(or however the memory-managment in perl is working - I dont know).

for (my $i = 0; $i < 5; $i ++)
{
  my @l = ($i .. 4);  # inside
  $X {$i} = \@l;
}

But can I produce the same output from above with using an outside variable?

Is that possible with some allocation trick - like to give it a new memory but not garbage the old one?

my %X = ();
my @l;  # outside
for (my $i = 0; $i < 5; $i ++)
{
    @l = ($i .. 4);
    $X {$i} = \@l;
}

All hash-elements now the the content of the last loop.

0 = 4
1 = 4
2 = 4
3 = 4
4 = 4

Is it possible to get the output from the beginning with the outer variable?

Upvotes: 0

Views: 70

Answers (1)

ikegami
ikegami

Reputation: 385819

No, it's not possible for each value of %X to be a reference to a different array, while at the same time all being a reference to the same array.

If you want each value of %X to be a reference to a same array, go ahead an allocate a single array outside of the loop.

If you want each value of %X to be a reference to a different array, you'll need to allocate a new array for each pass through the loop. This can be a named one (created using my), or an anonymous one (created using [ ]).


If you simply wanted to use the values within the outside @l so that every referenced array initially has the same value, you could use

my @a = @l;
$X{$i} = \@l;

or

$X{$i} = [ @l ];

Upvotes: 3

Related Questions