For Programmers: Free Programming Magazines  


Home > Archive > PERL Beginners > January 2006 > swap by reference?









You are viewing an archived Text-only version of the thread. To view this thread in it's original format and/or if you want to reply to this thread please [click here]

 

Author swap by reference?
.rhavin grobert

2006-01-30, 3:55 am

i understand that i can swap scalars by reference, eg:

sub swap {my $tmp=$_[0]; $_[0]=$_[1]; $_[1]=$tmp;}

....so when i say

$a = 'A';
$b = 'B';
swap $a, $b;

then a 'print $a;' gives me a 'B'....


now i want to do something similar with arrays - that i have to pass by
reference, eg:

swap \@a,\@b;

....but even if i can acces the arrays via '$$...' inside the sub, i
dont know how to swap the references. i know i could process the arrays
field by field but that isn't what i want.
What i want is to make the memory-adress behind the statements '@a' and
'@b' swap.
as far as i understand this, passing a reference (lets say $x=\$y) to a
sub and then (for example) undefining it ($x=undef;) doesn't undef $y.
doing the same with $$x=undef does undef $y.

so when i say
sub magic { $$_[0] = undef;}

then a magic(\@a); should undef array a, but it doesnt.

can anyone please explain this and tell me, what i'm doing wrong?

Paul Lalli

2006-01-30, 7:55 am

..rhavin grobert wrote:
> i understand that i can swap scalars by reference, eg:
>
> sub swap {my $tmp=$_[0]; $_[0]=$_[1]; $_[1]=$tmp;}
>
> ...so when i say
>
> $a = 'A';
> $b = 'B';
> swap $a, $b;
>
> then a 'print $a;' gives me a 'B'....


Waaay too much trouble you just went through.

$a = 'A';
$b = 'B';
($a, $b) = ($b, $a);
print "\$a: $a, \$b: $b\n";


> now i want to do something similar with arrays - that i have to pass by
> reference, eg:
>
> swap \@a,\@b;


$a = [1..5];
$b = ['a'..'e'];
($a, $b) = ($b, $a);
print "A: @$a, B: @$b\n";'


>
> ...but even if i can acces the arrays via '$$...' inside the sub, i
> dont know how to swap the references. i know i could process the arrays
> field by field but that isn't what i want.
> What i want is to make the memory-adress behind the statements '@a' and
> '@b' swap.
> as far as i understand this, passing a reference (lets say $x=\$y) to a
> sub and then (for example) undefining it ($x=undef;) doesn't undef $y.
> doing the same with $$x=undef does undef $y.
>
> so when i say
> sub magic { $$_[0] = undef;}
>
> then a magic(\@a); should undef array a, but it doesnt.
>
> can anyone please explain this and tell me, what i'm doing wrong?


You're not passing a mutable reference into the subroutine. You can't
change the reference that's created by \@a any more than you can change
the string "foobar". You have to store the reference in a variable and
change that variable.

@a = (1..5);
@b = ('a'..'e');
my ($a_ref, $b_ref) = (\@a, \@b);
swap ($a_ref, $b_ref);
sub swap {
my ($ref1, $ref2) = @_;
($_[0], $_[1]) = ($ref2, $ref1);
}
print "A: @$a_ref, B: @$b_ref\n";


But again, there's really no need for the subroutine. Just swap them
in a single list assignment.

Paul Lalli

Sponsored Links







Also available: Server administration forum archive | Web Design forum archive | Software forum archive | Hardware reviews archive

Copyright 2009 codecomments.com