Path: utzoo!utgpu!jarvis.csri.toronto.edu!cs.utexas.edu!usc!elroy.jpl.nasa.gov!jpl-devvax!lwall From: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Newsgroups: comp.lang.perl Subject: Re: Bug or misunderstanding? Message-ID: <7202@jpl-devvax.JPL.NASA.GOV> Date: 27 Feb 90 23:21:41 GMT References: <2860@uvaarpa.virginia.edu> <1990Feb27.174836.21449@iwarp.intel.com> Reply-To: lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) Organization: Jet Propulsion Laboratory, Pasadena, CA Lines: 99 In article <1990Feb27.174836.21449@iwarp.intel.com> merlyn@iwarp.intel.com (Randal Schwartz) writes: : In article <2860@uvaarpa.virginia.edu>, alfie%cs (Nick Holloway) writes: : | I am trying to split an array into two arrays. One will contain any : | elements that match any pattern in a pattern array, and the other : | contains all others. Here is the section of code that is causing me : | grief: : | : | @text = ( "Hello", "Joe", "Schmoe", "Gordon" ); : | @pat = ( "e", "o" ); : | text: for $text ( @text ) { : | for $pat ( @pat ) { : | if ( $text =~ /$pat/i ) { : | print "Match: $pat: $text\n"; : | next text; : | } : | } : | print "NoMatch: $text\n"; : | } : | : | I know that I am using the same name in different contexts, but arrays, : | constants and labels should have a separate namespace (right?). That's no problem. : | : | The problem seems to be with the "next text;" line. I need that there, : | since otherwise elements may be matched with more than one pattern. I : | can't use a "last;" just to skip the rest of the patterns, coz I need : | to keep elements that do not match. However, the above code does not : | work as expected. Here is the sample output : | : | Match: e: Hello : | Match: o: Joe : | NoMatch: Schmoe : | Match: o: Gordon : | : | Note that "Joe" did not match on the "e" but on the "o", and "Schmoe" didn't : | match at all! : | : | Have I misunderstood something vital? This is my first attempt to use : | labelled "next/last"s, and it is possible I have missed something in : | the manual. If so, I am open to suggestions of better ways of doing : | it. Perhaps if I spell Randal's name wrong, he'll give me a one liner :-) : | At the moment, I am inclined to think it is a bug. It WAS a bug till today. It wouldn't have been a bug in a language with decent exception handlers... : Well, here's the one-liner (but you spelled my name right): : : @hasit = grep(/e/i,@text); @neverhaditneverwill = grep(!/e/i, @text); You meant @hasit = grep(/[eo]/i,@text); @neverhaditneverwill = grep(!/[eo]/i, @text); : I use labled blocks quite a bit. Like, for a "loop...end loop" : sorta construct, instead of the C-like idiom of: : : LOOP: while (1) { : ... : ... : last LOOP if some_condition; : ... : ... : } : : I use: : : LOOP: { : ... : ... : last LOOP if some_condition; : ... : ... : redo LOOP; : } : : I guess I don't like to see that funky '1' there when it isn't being : evaluated. No, I haven't looked at the code to see if it actually got : optimized away. "while (1)" does get optimized, basically. And it'll be faster than your version, because it doesn't have to do a longjmp() at the end of every loop. Though I prefer "for (;;)" myself. Turns out you can just say "while ()" also, since that's what the middle term of the for loop translates into. It all comes out to the same thing internally. Except the redo version. : for (split(/(.)/,"Just another Perl hacker,")) {print if $_;} Interestingly, I had broken this here. It told me "split loop". So I unbroke it. Jest, the nether Perl heckler, Larry