alfie%cs.warwick.ac.uk@nsfnet-relay.ac.uk (Nick Holloway) (02/27/90)
[I am sending this via mailing list, since news is a bit dodgy here] 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?). 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. BTW. This shows up in perl 3.0 patchlevel 8 on a Sun4. -- JANET : alfie@uk.ac.warwick.cs | `O O' | Nick Holloway BITNET/EARN : alfie%uk.ac.warwick.cs@ukacrl | // ^ \\ | Comp Sci Dept INTERNET : alfie%cs.warwick.ac.uk@nsfnet-relay.ac.uk | Uni of Warwick UUCP : ..!mcsun!ukc!warwick!alfie, alfie@warwick.UUCP | Coventry, UK.
merlyn@iwarp.intel.com (Randal Schwartz) (02/28/90)
In article <2860@uvaarpa.virginia.edu>, alfie%cs (Nick Holloway) writes: | [I am sending this via mailing list, since news is a bit dodgy here] | | 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?). | | 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. Well, here's the one-liner (but you spelled my name right): @hasit = grep(/e/i,@text); @neverhaditneverwill = grep(!/e/i, @text); I got the same results as you running your code on a Sun3 rev 6. Your code should have worked (methinks). Larry? As a workaround (read: kludge), I got the right results with the following putziness: @text = ( "Hello", "Joe", "Schmoe", "Gordon" ); @pat = ( "e", "o" ); for $text ( @text ) { inner: { for $pat ( @pat ) { if ( $text =~ /$pat/i ) { print "Match: $pat: $text\n"; last inner; } } print "NoMatch: $text\n"; } } 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. for (split(/(.)/,"Just another Perl hacker,")) {print if $_;} -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/28/90)
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
emv@math.lsa.umich.edu (Edward Vielmetti) (02/28/90)
: 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 Uh huh. So any version of perl has to pass the "Just another Perl hacker," test, with all of Randal's one-liners generating the same output. (Does anyone have the complete collection to this point? It should be interesting study...) --Ed
merlyn@iwarp.intel.com (Randal Schwartz) (02/28/90)
In article <7202@jpl-devvax.JPL.NASA.GOV>, lwall@jpl-devvax (Larry Wall) writes: | : for (split(/(.)/,"Just another Perl hacker,")) {print if $_;} | | Interestingly, I had broken this here. It told me "split loop". So I | unbroke it. What??? You actually look at my signatures? And use them for testing? In that case, we oughta have them all in the .../t directory and make sure that "Just another Perl hacker," gets printed 89 zillion times for all future releases! mkdir("/tmp/$$",0777); chdir "/tmp/$$"; grep(open(X,">$_"),"1Just","2another","3Perl","4hacker,"); print join(" ",grep(s/^.//,<*>)); chdir ".."; system "rm -rf $$"; -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/
merlyn@iwarp.intel.com (Randal Schwartz) (02/28/90)
In article <EMV.90Feb27183449@duby.math.lsa.umich.edu>, emv@math (Edward Vielmetti) writes: | Uh huh. So any version of perl has to pass the "Just another Perl hacker," | test, with all of Randal's one-liners generating the same output. Deja vu! | (Does anyone have the complete collection to this point? It should | be interesting study...) Larry has been archiving comp.lang.perl, and the mailing list before it. *I've* only been saving what *other* people have written. And what do you mean, "interesting study"? I can see it now... "the warped mind of Randal vs. Perl... a case study in progressive degeneracy". :-) $_ = <<END; s/../pack('C',hex($&))/ge; print; 4a75737420616e6f74686572205065726c206861636b65722c END -- /=Randal L. Schwartz, Stonehenge Consulting Services (503)777-0095 ==========\ | on contract to Intel's iWarp project, Beaverton, Oregon, USA, Sol III | | merlyn@iwarp.intel.com ...!any-MX-mailer-like-uunet!iwarp.intel.com!merlyn | \=Cute Quote: "Welcome to Portland, Oregon, home of the California Raisins!"=/