[Za-pm] getting out of <STDIN> loop

Anne Wainwright anotheranne at fables.co.za
Tue Aug 11 12:44:00 PDT 2009


Francois, hi.

You have explained "in small understandable words" very clearly,
many thanks. Comments below.

On Tue, 11 Aug 2009 19:35:58 +0200
Francois Marais <francois at busii.com> wrote:

> Hi Anne
> 
> 2 reasons why your while loop does not terminate on empty input:
> 
> First, the 'length' issue: Before chomping, length of regexpr when
> you just press Enter is 1 (Still has the newline character) , after
> chomping it is 0 So you need to check after chomping or say
> 
>      ....
>      while (length($regexpr = <STDIN>)>1) {           # 1
>      ....
> 
> Secondly, after chomping, the empty string is still a defined value:
> 
> perl -e 'print "defined" if defined "" '

yes, I put that in and it prints "defined". I believe.

I am pasting here from a (bootleg?) online copy of "Learning Perl"
(which reads the same as my actual book) p.72 2nd edn.
http://docstore.mik.ua/orelly/perl/learn/ch06_01.htm
my *** emphasis
-----------------------------------
Typically, one thing you want to do is read all lines one at a time and
do something with each line. One common way to do this is:

while (defined($line = <STDIN>)) {
    # process $line here
}

*** As long as a line has been read in, <STDIN> evaluates to a defined
*** value, so the loop continues to execute. When <STDIN> has no more
*** lines to read, it returns undef, terminating the loop.
-----------------------------------
'no more lines to read' --> hit Enter???

so I put

if (defined($regexpr)) {print "defined";}

into my code, both before and after a chomp, and sure enough it prints
"defined" in both cases.

> 
> The reason why presumably the defined test is part of the loop, is
> that it if you enter
> Ctrl-D  (That is  on *nix) and dont check for it, and you use warnings
> (which you should be doing), you will get a warning
> 
> Ctrl-C is a *nix shell control character which terminates the
> command, so does not get to be processed in the while loop.
> 
> The reason all the files are printed out with an empty string is that
> it matches all the filenames
> 
> perl -e 'print "match" if "anyfilenameyoulike"=~//'
> perl -e 'print "match" if ""=~//'

I had concluded that a match must be the case but was at a loss to
explain why it happened. You demonstrate it clearly. The only way I can
put it into words is that // contains nothing that cannot be matched.
Is this a bug or a feature?

anyway that clearly explains the behavior observed there.

end of comments

many thanks
Anne
> 
> Regards
> 
> On Sun, Aug 9, 2009 at 2:39 PM, Anne Wainwright
> <anotheranne at fables.co.za>wrote:
> 
> > 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(".* *");
> > }
> > -----------------------------------------------------------
> >
> > 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.
> >
> > 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  :(
> >
> > Any one explaining this in small understandable words thanked
> > in advance.
> >
> > bestest
> > Anne
> > _______________________________________________
> > Za-pm mailing list
> > Za-pm at pm.org
> > http://mail.pm.org/mailman/listinfo/za-pm
> >


More information about the Za-pm mailing list