Hachi
Hachi

Reputation: 3289

Perl - Assign variables to values of references

There is a similar question How can I assign the result of a subroutine call to array references in Perl? but I'm curious about perl's possibilities

Is there a hack in perl to directly dereference element-wise an array of references?

in a code like

sub test { return([1..4],[5..8]); }
my (@a,@b);
my @result = test();
@a = @{$result[0]}; @b = @{$result[1]};

I would like to shorten the code to a simple statement like

sub test { return([1..4],[5..8]); }
my (\@a,\@b) = test();

or in a loop

foreach my $element (\"1",\"2",\"3") {
    my $dereferenced_element = $$element;

it would be nice to write something like

foreach my \$element (\"1",\"2",\"3") {

I know that this syntax doesn't make much sense, as I don't want to assign a value to the reference of a variable, but to assign a dereferenced value to the variable itself
but I'm curious if there is anything in that direction in perl's repertoire and I think this example shows the best, what I'm intending to do

Upvotes: 3

Views: 2748

Answers (4)

TLP
TLP

Reputation: 67900

The best way, IMO, is to assign the array refs to scalar variables, and dereference them as needed.

my ($x, $y) = test();

my @arrayx = @$x;
my @arrayy = @$y;

print "Element 1 in \$x is: $x->[1]\n";
for my $element (@$x) { ... }

You should also be aware that using $a and $b as variables is a bad idea, because they are predefined global variables used by the sort routine. They can be used, like most predefined variables, but it may lead to strange behaviour and hard to find bugs.

Upvotes: 0

tuxuday
tuxuday

Reputation: 3037

@Qtax answer is neat. I was wondering else it could be done. Not exactly what you asked for, but near.

sub test { return [1..3], [2..4]; }

my (%a);

@a{'ret1','ret2'} = test();

print @{$a{'ret1'}} ;
print @{$a{'ret2'}} ;

Upvotes: 1

Nylon Smile
Nylon Smile

Reputation: 9436

This is not answering your question regarding the direct de-referencing but

what you are doing in:

sub test { return([1..4],[5..8]); }
my (@a,@b);
my @result = test();
@a = $result[0]; @b = $result[1];

is not entirely correct, your @a and @b arrays become 2d arrays after this.

Instead you should say:

@a = @{$result[0]};
@b = @{$result[1]};

or, as you most probably already know:

my ($a, $b) = test();

or:

for my $element (test()) {
     # $element is an array ref
}

Upvotes: 2

Qtax
Qtax

Reputation: 33908

You can modify the globes directly if you want, but that is not a good practice.

sub test { return [1..3], [2..4]; }
(*x, *y) = test;
print "@x and @y";

Output:

1 2 3 and 2 3 4

This doesn't work with lexical (my) variables. To make it work with strict, you can declare the variables with our (instead of my).

Upvotes: 3

Related Questions