in reply to Re^2: $_ not set in while <>
in thread $_ not set in while <>
That condition is so dense you missed that it devolves into an infinite loop of prints and warns. Fixed:
while (1) { print "list of letters: "; defined( my $line = <> ) or last; $line !~ /\s*quit|exit|q\s*$/i or last; # Do something with $line. }
Update: Added missing my.
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re^4: $_ not set in while <>
by Marshall (Canon) on Jun 06, 2021 at 05:02 UTC | |
The condition is whether or not the input line is "quit" or some form of that. All that matters is the part after the last comma. Works fine for me: Update: I guess this could be, using "and" instead of comma. print() does return a true value, but nobody checks it. The comma operator is completely fine in Perl. This is more common in C code.
Update: Oh, the parens around the print are required in order to get the prompt onto the screen.
Another Update:
| [reply] [d/l] [select] |
by kcott (Archbishop) on Jun 06, 2021 at 06:28 UTC | |
G'day Marshall, I think the issue here is that the OP wrote "read a file", not "read from the keyboard". If the sentinel value is detected, then processing of the file should stop; however, I think it's reasonable to assume that if no sentinel value is detected, then processing of the file should stop at the end of the file. Note that in the examples below, I used a common alias of mine:
Here's a file that simulates your keyboard input. I've added an extra line that is to be ignored:
That is processed (almost) identically to your keyboard input:
I said "almost" because, as you may have noticed, there's a dangling "list of letters: " prompt as the last line of output. However, if there's no sentinel value, processing does not stop at the end of the file; instead, the code is stuck in a loop. Also, warnings are emitted. Both of those things are what ++ikegami predicted. Consider this slightly different input file (without a sentinel):
Here's what happens:
The screen output stopped there; I used Ctrl-C to get back to my shell prompt. Of course, I could've typed one of the sentinel values (quit|exit|q) but would you expect users to know what those values were; and even if they did, would you expect them to do this in the "production" environment you described. Update: I started to compose my response before your post had any updates. After posting, I see you've added three updates. That's not a complaint about the updates; just advice on what I was responding to. — Ken | [reply] [d/l] [select] |
by Marshall (Canon) on Jun 06, 2021 at 07:34 UTC | |
I suspect that something very simple like this would work:
| [reply] [d/l] |
by ikegami (Patriarch) on Jun 09, 2021 at 05:57 UTC | |
I didn't say it was dense. What does that even mean? At what point does something become dense? How can you claim it is or isn't dense? I said the "condition is so dense you missed that it devolves into an infinite loop of prints and warns." You tried to jam so much into a single expression that you got the expression wrong. Worse, and maybe even more importantly, it's very hard to notice that it's wrong because it's so dense. I only noticed when I rewrote your code.
How would you know? You didn't try giving EOF or an error. The fact that your code doesn't handle this immediately stood out after a rewrite.
Sure, but when it's so hard to read that errors crop in, and when the other alternative makes the error obvious, we start leaving the realm of subjectiveness and entering the realm of objectiveness. Also, it leaks the $line variable to the surrounding scope. Seeking work! You can reach me at ikegami@adaelis.com | [reply] [d/l] |
by LanX (Saint) on Jun 09, 2021 at 14:15 UTC | |
That's why he didn't care about checking defined for the line, since undef is a way to indicate EOF for files. But the special power of while(<>) is that he could call it on a file in @ARGV for testing those manual inputs
Cheers Rolf | [reply] [d/l] |
by ikegami (Patriarch) on Jun 09, 2021 at 19:06 UTC | |