Re: Exchanging Variables
by suaveant (Parson) on Aug 10, 2001 at 00:19 UTC
|
($first,$second) = ($second,$first);
- Ant
- Some of my best work - Fish Dinner
| [reply] [d/l] |
|
|
No way! You are saying that all I have to do is:
($first,$second) = ($second,$first);
and it automatically exchanges them for you?
Is there any other ways of doing this that might be used for other tasks? Or is this the only *reasonable* way to do it?
Mr.T
qw/"I pity da foo' who don't use Perl!"/; | [reply] [d/l] |
|
|
Asigning an array to a list of variables is a common way to give meaning full names to the items in an array. You can use it to make handling the returns of functions like local time easyer.
IE:
($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time);
as opposed to
@time = localtime(time);
and having to remeber that $time[2] is the hour.
If you have an array in the list on the left side of the = it will gobble up all the remaing items in the array on the right side.
You need to be careful of this, because anything following the array will not have anything asigned to it.
IE:
($one, $two, @three, $four) = ('one', 'two', 'three', 'four');
$one will equal 'one'
$two will equal 'two'
@three will equal ('three', 'four')
and $four will be undefined
There are many ways to use this feature of perl.
You will probably see
sub do_stuff {
my ($foo, $bar) = @_;
}
to get the arguments sent to a subroutine into named variables often.
| [reply] [d/l] [select] |
|
|
| [reply] |
|
|
Basically, whenever you assign to a list, each element gets assigned to, all in parallel. So, in parallel, the value of the first gets assigned to the second, and the value of the second (which isn't *yet* the previous value of the first) gets assigned to the first; thus, they get exchanged. See?
| [reply] |
|
|
push @INC, $first, $second; # not a temporary since it already exists!
$_= pop @INC foreach ($first, $second);
| [reply] [d/l] |
|
|
|
|
| [reply] |
Re: Exchanging Variables
by dailylemma (Scribe) on Aug 10, 2001 at 01:34 UTC
|
One way to swap two variables with no temporaries that isn't specific to perl is:
$a = $a ^ $b;
$b = $a ^ $b;
$a = $a ^ $b;
Update: The '^' operator is called "exclusive or" or XOR. It returns the bitwise XOR of the operands. XOR is equivalent to bitwise addition mod 2.
| [reply] [d/l] |
|
|
my $x = ["hello"];
my $y = ["world"];
print "We have \$x=$x and \$y=$y.\n";
print "The first element of \$x is '$x->[0]'\n";
print "The first element of \$y is '$y->[0]'\n";
print "Now swapping...\n";
$x = $x ^ $y;
$y = $x ^ $y;
$x = $x ^ $y;
print "We have \$x=$x and \$y=$y.\n";
print "The first element of \$x is '$x->[0]'\n";
print "The first element of \$y is '$y->[0]'\n";
What happened, of course, is that you stringified the object
and so lost the reference.
Now if you want a sneaky way to swap variables, the following takes a list of variables as arguments and rotates them. The first goes to the end, the rest move forward one. With 2 variables this just swaps.
my $x = ["hello"];
my $y = ["world"];
print "We have \$x=$x and \$y=$y.\n";
print "The first element of \$x is '$x->[0]'\n";
print "The first element of \$y is '$y->[0]'\n";
print "Now swapping...\n";
rotate($x, $y);
print "We have \$x=$x and \$y=$y.\n";
print "The first element of \$x is '$x->[0]'\n";
print "The first element of \$y is '$y->[0]'\n";
# And here is the magic bit
sub rotate { @_[0..$#_] = @_[1..$#_, 0]; }
# BTW here is something that won't work. Lists are not arrays! :-)
sub wont_rotate { @_ = @_[1..$#_, 0]; }
| [reply] [d/l] [select] |
|
|
I think I understand, but I am not exactly sure what the '^' operator does. Please forgive my ignorance, but what does it do, and what is it called? (In Perl.)
Mr.T
qw/"I pity da foo' who don't use Perl!"/;
| [reply] |
Re: Exchanging Variables
by Hofmator (Curate) on Aug 10, 2001 at 13:21 UTC
|
It should be clear by now, but for completeness sake I add
($one, $two, $three, $four) = ($three, $one, $four, $two);
# and array slicing
my @arr = qw/one two three four/;
@arr = @arr[2,0,3,1];
This shows that the whole construct works also for more than one element.
-- Hofmator
| [reply] [d/l] |
Re: Exchanging Variables
by robsv (Curate) on Aug 10, 2001 at 02:00 UTC
|
I also used to code in Pascal (never mind how long ago). If I was swapping two numerics, I used the XOR function. Here's the Perl version (since we ain't Pascal Monks):
$a = 598;
$b = 77;
$a = $a ^ $b;
$b = $a ^ $b;
$a = $a ^ $b;
print "$a $b\n";
Use the ($a,$b) = ($b,$a) version, though. I just put this up for fun: TMTOWTDI!
- robsv
Update: Aaargh! Ignore me. dailylemma posted this already. That's what I get for starting a reply, going for a soda, then finishing the reply. | [reply] [d/l] [select] |
Re: Exchanging Variables
by Anonymous Monk on Aug 10, 2001 at 04:14 UTC
|
( $first, $second ) = ( second, $first ); | [reply] |
Re: Exchanging Variables
by Anonymous Monk on Aug 10, 2001 at 10:23 UTC
|
($first, $second) = ($second, $first)
will do what you need | [reply] |
Re: Exchanging Variables
by Anonymous Monk on Aug 10, 2001 at 21:33 UTC
|
You could always use $_ as the temporary if you're concerned about taking space. | [reply] |