[comp.lang.perl] Strange while behaviour in sub ?

lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (02/06/91)

In article <1991Feb06.011642.14065@sdd.hp.com> ken@sdd.hp.com (Ken Stone) writes:
: Can anyone explain why this program works as it does ?  When I run it 
: as "./tp 1 2 3", I get
: 
: Using while loop:
: Got /dev/ptypc and /dev/ttypc
: Got /dev/ptypd and /dev/ttypd
: Got /dev/ptype and /dev/ttype
: 
: Using foreach loop:
: Got /dev/ptypc and /dev/ttypc
: Got /dev/ptypc and /dev/ttypc
: Got /dev/ptypc and /dev/ttypc
: 
: which seems really odd ... how in the heck is the while loop remembering 
: where it was in the </dev/pty*> expansion every time its called ?  We have
: put enough debug in to convince ourselves that its almost like the expansion
: is in a static of some sorts ?  Try running "./tp -v 1 2 3" to see what I
: mean.

Yes, </dev/pty*> has a built-in state, just as <FILEHANDLE> has a built-in
state.  The reason your foreach example didn't show this was that it
evaluates </dev/pty*> in an array context, which returns all the values.
Saying "while (</dev/pty*>)" supplies a scalar context, so it's going to
return the filenames one by one.  The </dev/pty*> has no idea it's being
called within a while loop, so exiting the loop doesn't reset it, just as
exiting "while (<FILEHANDLE>)" doesn't reset the file pointer back to the
beginning of the file.  </dev/pty*> is unlike <FILEHANDLE> in that it
does reset when you try to read past the end of the list, whereas the
file will just stay at EOF.  (However, <> resets to redo @ARGV or STDIN
in the same way.)

The each() function works similarly--it has a built-in iterator that returns
false only once before starting over.

Larry

ken@sdd.hp.com (Ken Stone) (02/06/91)

Thanks Larry ... that almost actually makes sense !!

  -- Ken

allbery@NCoast.ORG (Brandon S. Allbery KB8JRR) (02/09/91)

As quoted from <1991Feb06.011642.14065@sdd.hp.com> by ken@sdd.hp.com (Ken Stone):
+---------------
| which seems really odd ... how in the heck is the while loop remembering 
| where it was in the </dev/pty*> expansion every time its called ?  We have
+---------------

<...> is a filehandle reference --- even in this case, since <glob> is Perl
shorthand for a pipeline using sh, echo, and tr.  Thus, the state is
remembered as usual by the file, not by Perl doing something special with <>
in a while().

++Brandon
-- 
Me: Brandon S. Allbery			    VHF/UHF: KB8JRR on 220, 2m, 440
Internet: allbery@NCoast.ORG		    Packet: KB8JRR @ WA8BXN
America OnLine: KB8JRR			    AMPR: KB8JRR.AmPR.ORG [44.70.4.88]
uunet!usenet.ins.cwru.edu!ncoast!allbery    Delphi: ALLBERY

piet@cs.ruu.nl (Piet van Oostrum) (02/12/91)

>>>>> In message <11323@jpl-devvax.JPL.NASA.GOV>, lwall@jpl-devvax.JPL.NASA.GOV (Larry Wall) (LW) writes:


LW> Yes, </dev/pty*> has a built-in state, just as <FILEHANDLE> has a built-in
LW> state. 

Almost correct. The built-in state is in </dev/pty*>, but not in
<FILEHANDLE>. Rather it is in the filehandle itself, which means that
multip;le occurrences of <FILEHANDLE> share the same state (as long as they
refer to the same filehandle, meaning no locals, no open/close.

It is a pity you can't associate a file handle name to a globbing pattern,
but on the other hand you can always dump the thing in an array and work
from that.

LW> The each() function works similarly--it has a built-in iterator that
LW> returns false only once before starting over.

And in this case the state is in the ASSOC array.

There aren't many constructs that have state in the TEXTUAL OCCURRENCE.
?pattern? and /$regexp/o come to my mind, but the difference is crucial.
-- 
Piet* van Oostrum, Dept of Computer Science, Utrecht University,
Padualaan 14, P.O. Box 80.089, 3508 TB Utrecht, The Netherlands.
Telephone: +31 30 531806   Uucp:   uunet!mcsun!ruuinf!piet
Telefax:   +31 30 513791   Internet:  piet@cs.ruu.nl   (*`Pete')