Path: utzoo!utgpu!news-server.csri.toronto.edu!cs.utexas.edu!swrinde!zaphod.mps.ohio-state.edu!sdd.hp.com!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: Array modification rules (?) Keywords: splice perl array modifications Message-ID: <11091@jpl-devvax.JPL.NASA.GOV> Date: 17 Jan 91 19:59:37 GMT References: <29924@shamash.cdc.com> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 53 In article <29924@shamash.cdc.com> rrr@svl.cdc.com writes: : I often want to modify the array that is being used as the : iterator for a loop within that loop. Some examples, include : : - Scan the argument vector and remove or add args based on : what was specified. : - Scan an array and remove "uninteresting" elements : : To be safe, I have always used a temporary array in the : past. Is this necessary or are there well defined rules : for adding/deleting elements from the array being used as : the iterator within the scope of the iteration? The iterator in a foreach merely keeps an index into the array, and has no knowledge of any additions or deletions. In general, if you want to modify an array, it's better either to keep track of the current index yourself, or build a new array by shifting from the old array and pushing onto the new. This is just about as efficient as modifying the array in place, which entails copying blocks of pointers back and forth. As for removing "uninteresting" elements, this is typically done with grep(). You could even do some fancy processing with foreach, undef some of the elements of the array, and then say @foo = grep(defined, @foo). The only way to do this stuff in awk requires the use of both indexes and extra arrays. : Will this become patently obvious when my copy of "The Book" : arrives? In any event, I could not contain my curiosity any : longer. I don't think we mentioned that. We probably ought to have, but we concentrated more on saying what you can do, not what you shouldn't. Perl itself is usually pretty good about telling you what you shouldn't do. :-) : Assuming the rules are formalized and "intuitive" it could : be useful for a lot of cases. I played with the following : little piece to determine that there is some method to what : happens. : : @a=split(//,"%xJaubsctd eafngohtihjekrl mPneorplq rhsatcukvewrx"); : for (@a) {splice(@a,0,1);$x .= $_;} print "$x\n"; I don't think I want to guarantee the current behavior of foreach in the presence of array modification. There are possible ramifications with referencing things that no longer exist. On top of which, it's not clear to me why the above doesn't start by outputting a %. On the other hand, it's a pretty safe bet that the behavior won't change any time soon... Larry