2011-10-11 104 views
1

我有一個while循環可以工作。我想要捕獲該循環內的擊鍵,但ReadKey例程會暫停封閉循環。我究竟做錯了什麼?Term :: ReadKey在一個循環中暫停封閉循環

#!/usr/bin/perl 

use strict; 
use warnings; 
use Term::ReadKey; 

my $char; 

while(1 < 5) { 
    print time . "\n"; 

    while(1) { 
     ReadMode('raw'); 
     $char = ReadKey(0); 
     print "Got $char\n"; 
    } 
    sleep(5); 
} 

回答

1

從你的問題和你發佈你想要完成的代碼中不完全清楚。一方面,這個問題聽起來好像你試圖獲得非阻塞式閱讀。如果是這樣的話,你可能想要更多的東西像這樣爲你的內部循環:

while(1) { 
    ReadMode('cbreak'); 
    my $char = ReadKey(-1); 
    next unless defined($char); 
    print "Got $char\n"; 
    last if $char eq "\t"; 
} 

ReadKey(-1)建立了一個非阻塞讀,這意味着它不會等待輸入;它只是告訴你輸入是什麼,如果有的話,然後繼續下一次迭代。如果沒有輸入,它會返回undef。您會注意到我將ReadMode切換爲'cbreak',用於測試目的,以便在準備終止時輕鬆點擊CTRL-C。在這個示例代碼中,Hitting選項卡也會終止。由於ReadMode()設置爲-1,對於非阻塞,我們只是保持循環。

您的代碼還有問題「while(1 < 5)」。你覺得這樣做對你有什麼好處? 1總是小於5,這樣循環永遠不會終止。如果你真的想要一個永無止境的循環,只要說while(1),所以我們知道你知道你的意思。另一方面,我認爲你可能真的想說一些類似while($i++ < 5)的東西,這樣你至少會得到5次外循環的迭代。

最後一個注意事項。無論您設置了什麼「ReadMode」,在退出該程序之前,您確實應該調用「ReadMode('restore')」,否則您的終端可能會保持「愚蠢」。例如,在我的程序末尾沒有放置ReadMode('restore');,按回車鍵不會在我的終端中給我一個新的行。這個模塊在終止後似乎沒有清理完畢,所以你必須明確地做。

您還應該查看Term::ReadKey的文檔。如果你看,大部分我在這裏討論的東西都是在那裏閱讀的。

+0

1 <5是我正在測試的舊代碼。它應該是(1),正如你指定的那樣。我試圖完成的事情很簡單:在主循環(1 <5)的while循環中,我從外部數據源提取數據並顯示它。然後在顯示數據後的主循環中,我切換ReadMode,以便捕捉鍵。在while循環捕捉擊鍵後,我睡覺(5)並重新開始。但是,ReadKey的while循環會暫停父循環,因此刷新不會發生。 – gdanko

+0

實際的代碼可以在這裏找到:http://pastebin.gdanko.net/459行24被執行並且數據被顯示。我不認爲第32行的睡眠聲明會被擊中,所以下一次迭代不會被執行。 – gdanko

+0

這就是發佈不相關代碼的問題:我們不知道你在內部while()循環的內部和外部都進行了輸入,這有所作爲。內部while()循環結束後面的下一行需要設置ReadMode('restore')。 'cbreak'或'raw'模式會污染您的其他輸入源。 – DavidO