Here's another "What's a quick and real neat way of...." type question

Shaun McCarthy shaunm at
Thu Nov 14 15:03:55 CST 2002

I think that perl has C side effects, so (my($a, $b) = (shift @a, shift @b)) will return the array assigned to the if statement, so if you go: (my($a, $b) = (shift @a, shift @b))[0] you will get the value assigned to a, which will be undef when they arrays runs out (assuming the same length thing), which equates to false.
while ((my($a,$b) = (shift @a, shift @b))[0]) {
should do the trick... Unfortunately I am off site and don't have access to a perl instance, but I think it should work quite well. A comment above the while loop will help who ever comes across it next understand it though :P

	-----Original Message----- 
	From: Grant McLean 
	Sent: Fri 15/11/2002 7:40 a.m. 
	To: Piers Harding; Enkidu 
	Cc: wellington-pm-list at 
	Subject: RE: Here's another "What's a quick and real neat way of...." type question

	Piers Harding wrote:
	> On Thu, Nov 14, 2002 at 11:06:14PM +1300, Enkidu wrote:
	> > Is there a neat way of looping through *both arrays* at
	> > the same time?
	> how about this:
	> while (my ($a, $b) = (shift @a, shift @b)){
	>   do the funky thing with $a and $b ....
	> }
	Interesting suggestion, I wouldn't have expected that to
	work, since when @a and @b are empty, the right hand
	side of the expression (shift @a, shift @b) evaluates to
	(undef, undef) which is a two element list which in boolean
	terms is 'true', so the while loop should never exit.
	My curiosity was piqued, so I tried it.  The bad news is it
	doesn't work :-(  The good news is I was right ;-/
	One approach is to add a line to explicitly break out of
	the loop when the arrays are empty:
	  while (my ($a, $b) = (shift @a, shift @b)){
	    # do the funky thing with $a and $b ....
	    last unless(@a);
	At first, I made the mistake of adding this check as the
	first line of the loop.  This meant the loop skipped the
	last element of each array since when the last element was
	successfully shifted off, there was nothing left in the
	array.  So, the test needs to go either at the end of the
	loop. (I also tried putting it in a continue block but it
	didn't work - I guess 'last' won't break out of the main
	block when you call it from another block).
	It is possible to combine the test with the assignment in
	such a way that the right hand side evaluates to an empty
	list when the arrays are empty:
	  while(my($a, $b) = (@a ? (shift @a, shift @b) : ()) ){
	    # do the funky thing with $a and $b ....
	Anyone have a more elegant solution?
	PS: I'm assuming @a and @b are the same length.
	Grant McLean        BearingPoint Inc - formerly The Web Limited
	+64 4 495 9026           Level 6, 20 Customhouse Quay, Box 1195
	gmclean at                Wellington, New Zealand

More information about the Wellington-pm mailing list