Do not use diamond for STDIN
by merlyn (Sage) on May 02, 2001 at 17:58 UTC
|
Besides the points made in Re: Loop Control : REDO, you should never use the diamond
with interactive I/O like prompting. Use <STDIN> instead.
Otherwise, your day will be very miserable when someone types a filename
on the command line. You'll still get all those prompts, and it'll look very
funky.
As an alternative, say print ... if $ARGV eq '-', then you'll only be prompting
if you're actually reading from STDIN. The output-only results printing can
be unconditional.
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] [select] |
|
|
Sir,
It seems like this may be a very desireable action at times. EG. in the case where you want a script to be interactive, but also have it cronned with all of the values for it in another file. In which case <> will do exactly what you want in both cases. Isn't this more a question of style that what SHOULD/SHOULDN'T be done?
-Fatty Lumpkin
Update: Merlyn is 1000% correct, poor reading on my part, i missed the actual printed prompt.I am just used to doing something like
shift || (print "\nprompt:" and <>);
But that doesn't allow for this behavior either.I missed the point, Thanks for correcting me. | [reply] [d/l] |
|
|
| [reply] |
Re: Loop Control : REDO
by suaveant (Parson) on May 02, 2001 at 17:40 UTC
|
You are gonna smack yourself... you put a $1(one) instead
of $i in your checks...
It works then but allows letters... maybe wrap it in an
int()?
Update Wrapping it in an int makes letter entries
zero, maybe instead of chomp do
#!/prod/gnu/bin/perl
print "** Random 4 Lotto Numbers **\n";
print "** Type any four digits (0 to 9) **\n\n";
for ($i=1; $i <= 4; $i++) {
print "Choice $i: ";
($digit[$i] = <>) =~ s/\D//g;
redo unless $digit[$i];
redo if $digit[$i] > 9;
redo if $digit[$i] < 0;
}
print "Your choices :@digit \n";
then you just get the numbers.
- Ant | [reply] [d/l] |
|
|
Thanks suaveant for spotting the typo. The example came in the cd but i didn't spot that.
| [reply] |
|
|
And if you're going to test the input with a regular
expression, then use that on the redo line:
print "** Random 4 Lotto Numbers **\n";
print "** Type any four digits (0 to 9) **\n";
for ($i=1; $i <= 4; $i++) {
print "Choice $i: ";
chomp ($digit[$i] = <STDIN>);
redo if $digit[$i] !~ /^\d$/;
}
print "Your choices :@digit \n";
iakobski | [reply] [d/l] |
|
|
redo if $digit[$i] =~ /\D/
-- Randal L. Schwartz, Perl hacker | [reply] [d/l] [select] |
|
|
|
|
yours is good, but why chomp? no need with that regexp...
print "** Random 4 Lotto Numbers **\n";
print "** Type any four digits (0 to 9) **\n";
for ($i=1; $i <= 4; $i++) {
print "Choice $i: ";
redo if ($digit[$i] = <STDIN>) !~ /^\d$/;
}
print "Your choices :@digit \n";
since the $ works fine with \n there
- Ant | [reply] [d/l] |
|
|
|
|
(boo)Re: Loop Control : REDO
by boo_radley (Parson) on May 02, 2001 at 18:24 UTC
|
Although I imagine that what you're reading is probably just trying to explain loops in perl, that's probably not the best way to do things...
use strict;
print "** Random 4 Lotto Numbers **\n";
print "** Type any four digits (0 to 9) **\n";
my @digit;
foreach my $i (1..4){
while ($digit[$i] =~/^[\D]$/){
print "enter digit $i : ";
chomp($digit[$i] =<>)};
}
print "Your choices : @digit \n";
As an aside, I thought that redo and friends were only applicable inside of while or foreach loops, but apparently, that's not the case. Hm! | [reply] [d/l] |
|
|
foreach my $i ( 0..3){
or if not the print should be:
print "Your choices : @digit[1..4] \n";
iakobski
| [reply] [d/l] [select] |
|
|
| [reply] [d/l] |
|
|
well, YES, that is true.
however, from perl's documentation on continue :
If there is a continue BLOCK attached to a BLOCK (typically in a while or foreach)...
which made me believe you could tack continues on to any block all willy nilly. This isn't the case, though.
| [reply] |
|
|