[Za-pm] getting out of <STDIN> loop
Anne Wainwright
anotheranne at fables.co.za
Tue Aug 11 12:57:42 PDT 2009
Oskar, lotsa thanks,
comment below at end.
On Mon, 10 Aug 2009 02:44:54 +0100
Oskar Pearson <oskar at deckle.co.za> wrote:
> Hi
>
>
> > Hi, all,
> >
> > (Am in fact referring to Exercise 2 Chapter 2 of
> > Schwartz et al INTERMEDIATE PERL.)
> >
> > First, while realising that the official solution is a masterpiece
> > of condensed perl code, I don't understand why the first
> > line has the (1) ).
> >
> > -----------------------------------------------------------
> > while(1) {
> > print "Enter a regular expression to match filenames> ";
> > chomp(my $regex = <STDIN>);
> > last unless (defined $regex && length $regex);
> > print map {" $_\n"} grep {eval{/$regex/}} glob(".* *");
> > }
> > -----------------------------------------------------------
>
> The while loop continues indefinitely - the value is always true, so
> it'll loop until the "last" gets hit.
>
> There are two reasons that happens - the "end of file" (pressing
> control-D will do that), or if the length of the input is 0 (when
> someone inputs a blank line - assuming it's "chomped"). That's what
> this line means:
> > last unless (defined $regex && length $regex);
>
>
>
>
> > My own more primitive solution fails to get out of the
> > input loop, albeit with simpler criteria. My code is:
> >
> > -------------------------------------------------------
> > opendir THISDIR, "." or die "serious braindamage: $!";
> > @allfiles = readdir THISDIR;
> > closedir THISDIR;
> >
> > while (defined($regexpr = <STDIN>)) { # 1
> > chomp $regexpr;
> > foreach $file(@allfiles) { # 2
> > if ($file =~ m/$regexpr/) { # 3
> > print "$file\n";
> > } # -3
> > } # -2
> > } # -1
> > -------------------------------------------------------
> > Essentially on no regex input it outputs all the files as if ".+"
> > had been input.
>
> First hint is that you should use "perl -w" and "use strict;" -
> you'll need to declare your variables though.
>
> > I thought the line marked #1 was a dead ringer for getting out of
> > the input loop. (p.72 Chapter 6 of Schwartz et al LEARNING PERL).
> > If I take
> > "&& length $regex" out of their code then that also fails to exit. I
> > don't understand :(
>
> Pseudocode for their version:
>
> Loop forever (unless we hit the "last below, of course") {
> print something
> read something from stderr
> Unless I got a valid input value, and that input value has a
> valid length, then jump out of this loop
> Do the regex stuff
> }
>
>
>
>
>
> > opendir THISDIR, "." or die "serious braindamage: $!";
> > @allfiles = readdir THISDIR;
> > closedir THISDIR;
> >
> > while (defined($regexpr = <STDIN>)) { # 1
> > chomp $regexpr;
> > foreach $file(@allfiles) { # 2
> > if ($file =~ m/$regexpr/) { # 3
> > print "$file\n";
> > } # -3
> > } # -2
> > } # -1
>
>
>
> I'd prefer to change this as follows. I'm using slightly different
> structures here.
>
> #!/usr/bin/perl -w
> use strict;
> opendir THISDIR, "." or die "serious braindamage: $!";
> my @allfiles = readdir THISDIR;
> closedir THISDIR;
>
> while (my $regexpr = <STDIN>) { # If this is
> undefined here, the "while" is a while of an undef value, and the
> while will terminate chomp $regexpr;
> last unless length($regexpr); #If I
> got a blank line, jump out
> foreach my $file (sort(@allfiles)) { # Sort
> for consistency if ($file =~ m/$regexpr/i) {
> # guessing you probably want /i heere
all my filenames are in small print ;)
> print "$file\n";
> }
> }
> }
>
> Hope that helps!
Yes, bigly! Very clear and exactly how I would have written it if I
could have ;)
Along with the analysis of the why things did what they did from
Francois I can now move on.
Anne
>
> Oskar
More information about the Za-pm
mailing list