[英]perl - weird loop behavior with ReadKey
出於某種原因,在我的簡單菜單程序中,由於ReadKey()而發生了奇怪的事情
#!/usr/local/bin/perl
use strict ;
use warnings ;
use English ;
use Term::ReadKey ;
my @available_choices = ('choice one', 'choice two', 'choice three') ;
my $array_size = scalar (@available_choices) ;
print "\nPlease make your selection from the options below:\n\n" ;
for (my $i=0, my $j=1 ; $i < $array_size ; $i++, $j++) {
print "$j) $available_choices[$i]\n" ;
}
my $key = undef ;
for (my $k=0; $k < 5; $k++) {
print "\nSelection :> " ;
$key = ReadKey();
if ((defined $key) && ($key =~ /[1-$array_size]/)) {
print "\nYou selected \"$available_choices[$key-1]\"\n" ;
last ;
}
else {
sleep 1 ;
}
}
因此,如果您運行此簡單程序並選擇1、2或3,則它將按預期工作。 如果您輸入其他任何內容(以觸發else塊),則循環將重復3或4次,直到ReadKey()再次接受輸入。 最好用此輸出說明(我輸入xxx,然后在輸入yyy之前打印了3次“ Selection:>”):
$ ./bar.pl
Please make your selection from the options below:
1) choice one
2) choice two
3) choice three
Selection :> xxx
Selection :>
Selection :>
Selection :>
Selection :> yyy
這是因為ReadKey
讀取密鑰 。 當您按x 3次,然后按Enter時 ,這是4個鍵。 實際上,即使是正確的選擇( 1 Enter )也有2個鍵。 您只是沒有注意到,因為您的程序會立即退出。
這不太明顯,因為默認輸入模式會緩沖擊鍵,直到您按Enter鍵為止。 屆時, ReadKey
將開始一次返回每個擊鍵。
解決方案取決於您要尋找的行為。 如果要在對輸入進行操作之前必須先按Enter鍵 ,則可以一次讀取一行(使用標准<>
運算符)。 您根本不需要Term::ReadKey
。
如果要在按鍵后立即采取措施,則需要使用Term::ReadKey
的ReadMode
函數來更改輸入緩沖。 程序退出時,請不要忘記添加END { ReadMode(0) }
以恢復原始模式。
看起來您的程序讀取了一個鍵,進入else循環並在您鍵入其他字符時進入睡眠狀態,然后繼續。 您可能正遭受緩沖的困擾,因為在使用睡眠時不會立即進行打印。
您的程序可以使用一些替代方法。 這是一個例子:
use strict;
use warnings;
use v5.10;
my @available_choices = ('choice one', 'choice two', 'choice three') ;
print "\nPlease make your selection from the options below:\n\n" ;
# Using a block to reduce scope of $i
# No need to use a separate variable for the array length
{
my $i = 0;
say ++$i, ") $_" for @available_choices;
}
# No need to use a temp variable for a loop
# Also, might be better off with an infinite loop,
# rather than one with 5 cycles.
#for (0 .. 4) {
while (1) {
print "\nSelection :> " ;
chomp(my $key = <>); # Using STDIN instead of ReadKey
last if $key =~ /^q$/i; # easy exit
next unless $key =~ /^\d+$/;
if (defined $available_choices[$key-1]) {
say qq(\nYou selected "$available_choices[$key-1]"\n);
last;
}
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.