halbert@halbert.crl.dec.com (Dan Halbert) (05/09/90)
(Using Perl version: $Header: perly.c, v 3.0.1.4 90/02/28 18:06:41 lwall Locked $ Patch level: 15) I'm writing an interactive terminal program in perl. It prompts the user and reads from STDIN. If you try this program: print "prompt: "; $a = <STDIN>; print $a; then a carriage return will end the input. (That is, <STDIN> will read one line.) However, if you try: print "prompt: "; local ($a) = <STDIN>; print $a; then STDIN keeps reading input until I type ^D. In my program, the local() is in a subroutine, of course, but that isn't necessary to reproduce the problem. Opening "-" explicitly doesn't solve the problem. I just started looking at comp.lang.perl; sorry if this is old hat. --Dan Halbert
tneff@bfmny0.UU.NET (Tom Neff) (05/09/90)
In article <5249@crltrx.crl.dec.com> halbert@crl.dec.com writes: >print "prompt: "; >$a = <STDIN>; >print $a; > >then a carriage return will end the input. (That is, <STDIN> will read >one line.) >print "prompt: "; >local ($a) = <STDIN>; >print $a; > >then STDIN keeps reading input until I type ^D. The local() construction is treated as an array. As the manual states, $var=<FILE> reads one line but @array=<FILE> reads the whole thing. The workaround is to say print "prompt: "; local ($a); $a = <STDIN>; print $a; -- "NASA Awards Acronym Generation :(%( : Tom Neff System (AGS) Contract For Space : )%): tneff%bfmny@UUNET.UU.NET Station Freedom" - release 1989-9891 :(%( : ...!uunet!bfmny0!tneff
merlyn@iwarp.intel.com (Randal Schwartz) (05/10/90)
In article <5249@crltrx.crl.dec.com>, halbert@halbert (Dan Halbert) writes: | (Using Perl version: | $Header: perly.c, v 3.0.1.4 90/02/28 18:06:41 lwall Locked $ | Patch level: 15) | | I'm writing an interactive terminal program in perl. It prompts the user | and reads from STDIN. | | If you try this program: | | print "prompt: "; | $a = <STDIN>; | print $a; | | then a carriage return will end the input. (That is, <STDIN> will read | one line.) | | However, if you try: | | print "prompt: "; | local ($a) = <STDIN>; | print $a; | | then STDIN keeps reading input until I type ^D. | | In my program, the local() is in a subroutine, of course, but that isn't | necessary to reproduce the problem. | | Opening "-" explicitly doesn't solve the problem. | | I just started looking at comp.lang.perl; sorry if this is old hat. Not old hat. I don't recall seeing this one before. But, the problem (without testing it) is that local($a) = <STDIN>; is an _array assignment_. So, <STDIN>, being very helpful, is sucking all of standard input into an array, and then giving the first line into $a, while discarding the rest. This works better (but looks ugly -- Larry?): local($a) = "".<STDIN>; Which basically says to interpret <STDIN> in a scalar context (a string concatenation), and pass the result to the assignment. $|=1;$_=",rekcah lreP rehtona tsuJ";while(length){exit wait if fork;s/.$//;print$&;} -- /=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) (05/10/90)
In article <5249@crltrx.crl.dec.com> halbert@crl.dec.com writes:
: However, if you try:
:
: print "prompt: ";
: local ($a) = <STDIN>;
: print $a;
:
: then STDIN keeps reading input until I type ^D.
:
: In my program, the local() is in a subroutine, of course, but that isn't
: necessary to reproduce the problem.
This is because local is really just a modifier on a list lvalue, so
you're really doing the same as the following:
local($a);
($a) = <STDIN>;
Since ($a) is a list, the <STDIN> is being evaluated in an array context,
and returning the entire file.
You could force a scalar context by concatenating a null string, but it's
probably more efficient to separate it out thusly:
local($a);
$a = <STDIN>;
Larry