Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!usc!elroy.jpl.nasa.gov!sdd.hp.com!wuarchive!udel!haven.umd.edu!uvaarpa!mmdf From: bjaspan@ATHENA.MIT.EDU (Barr3y Jaspan) Newsgroups: comp.lang.perl Subject: Add 'continue' to 'foreach'? Message-ID: <1991May8.015608.19707@uvaarpa.Virginia.EDU> Date: 8 May 91 01:56:08 GMT Sender: mmdf@uvaarpa.Virginia.EDU (Uvaarpa Mail System) Reply-To: bjaspan@ATHENA.MIT.EDU Organization: The Internet Lines: 72 I have a perl program in which I am doing a select() on a large number of sockets and then iterating over those that get set. Initially, I was doing this for ($i=0; $i < $maxfn; $i++) { next unless vec($rdset, $i, 1); # stuff } where $maxfn happens to be the largest filedescriptor number in $rdset. Since vec() is slow, I am now doing something like this (note that I have to maintain $i in any event, because I have several arrays keyed on it): @rdset = split(//, unpack('b*', $rdset)); $i = 0; foreach (@rdset) { if (! $_) { $i++; next; } # stuff $i++; } The block attached to the 'if' is ugly, and this is perl, so there should be a magic way around the problem. (Also, in a recent posting, someone said that having a block like that is slower than doing it with a postfix if/unless. Clearly, if there is a local() inside the block there will be overhead; does Perl not optimize if there is no local()?) How about adding an optional continue block to the foreach statement? Then I could do something like this: $i = 0 foreach (@rdset) { next unless $_; # stuff } continue { $i++; } The advantage to doing it this way is that foreach is non-destructive. Doing it with a while (which has a continue block) would require shifting the array, which (1) would mean I couldn't use it again, or I would have to keep a copy, and (2) I would guess is slower than just iterating over the elements. ----------- As a separate issue, I just thought of another way to do it (after all, this is perl): $rdstr = unpack('b*', $rdset); $i = length($rdstr); while (chop $rdstr) { next unless $_; # stuff } continue { $i--; } This saves a split(), and adds a length() and a bunch of chop()s; it also iterates backwards (although this doesn't matter in this particular case). Is this faster? (ie: how fast is chop?) $_ = "\n,rekcah lrep rehtona tsuJ"; print chop while $_; Barr3y Jaspan, bjaspan@mit.edu