在 Perl 中,当用户输入无效输入时,如何要求用户重新输入?
我有一个 Perl 子例程,它要求用户输入。我在该子例程本身内部执行检查输入的输入是否有效。
如果不是,我想再次调用子例程,让用户这次输入有效的输入。
我的子例程如下:
sub some_routine {
print "Enter a number to select (1) Apple (2) Mango (3) grapes:"
$value=STDIN;
if($value =~ /[^1-3]/ ) {
print "The input is not valid!";
print "Do you want to continue selecting a fruit again (Y or N)?";
$choice = STDIN;
if( $choice eq "y") {
### I want to call the subroutine again to enter input ###
} else {
exit;
}
}
}
那么如何在其中递归子例程呢?
I've a Perl subroutine which asks input from User. I perform a check inside that subroutine itself whether the input entered is a valid input.
If it's not, I want to call the subroutine again to let the user enter a valid input this time.
My subroutine is as follows:
sub some_routine {
print "Enter a number to select (1) Apple (2) Mango (3) grapes:"
$value=STDIN;
if($value =~ /[^1-3]/ ) {
print "The input is not valid!";
print "Do you want to continue selecting a fruit again (Y or N)?";
$choice = STDIN;
if( $choice eq "y") {
### I want to call the subroutine again to enter input ###
} else {
exit;
}
}
}
So how to recurse a subroutine in this?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(9)
使用 IO::Prompt 模块。
有了它,你可以这样写:
Use IO::Prompt module.
With it you can write it like this:
您的输入不是 eq“y”,而是“y\n”。
如果您将该行更改为
if ($choice =~ /^[Yy]/)
这将确保您在输入开头捕获 Y,而不用担心 y 或 yes 或 Y 或是的。作为帮助,您应该使用
而不是单独使用STDIN
。始终添加use strict;使用警告;
在顶部。这确保您需要使用以下方式定义 $value 和 $choice:正如其他人提到的。作为循环,这可能更简单。
Your input is not eq "y" but "y\n".
If you change the line to
if ($choice =~ /^[Yy]/)
this will make sure you catch the Y at the start of the input and not worry about y or yes or Y or Yes.As a help, you should use
<STDIN>
instead ofSTDIN
alone. Always adduse strict; use warnings;
at the top. This makes sure you need to define $value and $choice using:As other people have mentioned. This is probably more straightforward as a loop.
我使用的是一个简单的 goto:
这是一种非常幼稚的方法,但适合初学者。
What I use is a simple goto:
This is a very naive way but works for the beginners.
要在 Perl 中递归地调用子例程,您只需从子例程本身调用子例程,就像在任何其他语言中一样:
但是,您实际上并不希望将递归用于“重复直到条件更改”场景。
这就是
while
循环的用途:To call a subroutine recursively in Perl, you just call the sub from itself, the same as in any other language:
However, you don't really want to use recursion for a "repeat until condition changes" scenario.
That's what
while
loops are for:没有理由为此使用递归。一个简单的 while 循环就可以了。
如果
validate_input
返回 0,则循环将重复。There's no reason to use recursion for this. A simple
while
loop will do.If
validate_input
returns 0, the loop will repeat.递归
goto - 尾调用优化 (TCO)
或重做
等等...
recursive
goto - Tail Call Optimization (TCO)
or redo
and so ...
调用例程的正确方法是
......因为您拥有的是尾部调用 - 这是您在函数中执行的最后一件事。如果你正常调用它,你会为每次调用吃一个堆栈帧,并且内存分配会增加。像这样调用,您可以重复使用相同的堆栈帧。从你作为程序员的角度来看,这
与不吃内存是一样的。
这仅适用于将自己称为最后一件事的例程 - 在其他情况下,您确实应该切换到其他人建议的 while 循环(并且,为了代码的吸引力,您可能想要无论如何都要这样做)。
The correct way to call the routine is
...because what you have is a tail call - it's the last thing you do in your function. If you call it normally you eat a stack frame for each call and memory allocation goes up. Called like this, you re-use the same stack frame. From your perspective as a programmer, this is the same as
but without eating memory.
This only works for routines that call themselves as the last thing they do - in other cases, you should indeed be switching to the while loop that other people suggest (and, for code attractiveness, you may want to do that anyway).
编辑:出于各种原因(风格、性能等...),我强烈建议不要在这里进行递归调用,而是在 while 循环中检查它< /强>。
[原始回答者的免责声明]“从风格的角度来看,我不会在这里进行递归调用,而是在 while 循环中检查它,但我想在某种程度上,这也是一个品味问题。”
就使用递归而言,作为示例,您可以从函数内部调用该函数,如下所示:
EDIT: For a variety of reasons (style, performance, etc...), I would strongly advise not do a recursive call here, though, but rather check it in a while loop.
[Original answerer's disclaimer] "From a style perspective, I would not do a recursive call here, though, but rather check it in a while loop, but I guess to a degree, that's a matter of taste as well."
As far as using recursion, as an example, you can just call the function from within the function, like so: