傳回目前選取的檔案控制代號。如果提供 FILEHANDLE,則設定新的預設目前輸出檔案控制代號。這有兩個影響:首先,沒有檔案控制代號的 write
、print
或 say
會預設為此 FILEHANDLE。其次,與輸出相關的變數參考會參考此輸出頻道。
例如,若要設定多個輸出頻道的頁首格式,可以執行下列動作
select(REPORT1);
$^ = 'report1_top';
select(REPORT2);
$^ = 'report2_top';
FILEHANDLE 可以是表達式,其值提供實際檔案控制代號的名稱。因此
my $oldfh = select(STDERR); $| = 1; select($oldfh);
有些程式設計師可能比較喜歡將檔案控制代號視為具有方法的物件,並偏好將最後一個範例寫成
STDERR->autoflush(1);
(在 Perl 版本 5.14 之前,您必須先明確地使用 use IO::Handle;
。)
儘管您可以使用 select
暫時「擷取」 print
的輸出,如下所示
{
my $old_handle = select $new_handle;
# This goes to $new_handle:
print "ok 1\n";
...
select $old_handle;
}
您可能會發現將 typeglob 本地化更容易
{
local *STDOUT = $new_handle;
print "ok 1\n";
...
}
這兩個並不完全相等,但後者可能更清楚,並且如果封裝的程式碼發生錯誤,它將還原 STDOUT。不同之處在於,在前者中,仍然可以使用 print
陳述式(例如 print STDOUT ...
)中的 STDOUT 來存取原始 STDOUT,而在後者中,STDOUT 處理本身的意義已暫時更改。
可攜性問題:"select" in perlport。
這會呼叫 select(2) 系統呼叫,並使用指定的位元遮罩,可以使用 fileno
和 vec
沿著這些行來建構
my $rin = my $win = my $ein = '';
vec($rin, fileno(STDIN), 1) = 1;
vec($win, fileno(STDOUT), 1) = 1;
$ein = $rin | $win;
如果您想選擇許多檔案處理,您可能希望撰寫一個像這樣的子常式
sub fhbits {
my @fhlist = @_;
my $bits = "";
for my $fh (@fhlist) {
vec($bits, fileno($fh), 1) = 1;
}
return $bits;
}
my $rin = fhbits(\*STDIN, $tty, $mysock);
通常的慣用語是
my ($nfound, $timeleft) =
select(my $rout = $rin, my $wout = $win, my $eout = $ein,
$timeout);
或僅執行此操作以封鎖,直到某個項目準備就緒
my $nfound =
select(my $rout = $rin, my $wout = $win, my $eout = $ein, undef);
大多數系統不會費心在 $timeleft
中傳回任何有用的內容,因此在標量內容中呼叫 select
只會傳回 $nfound
。
任何位元遮罩也可以是 undef
。如果指定逾時,則以秒為單位,可以是分數。注意:並非所有實作都能傳回 $timeleft
。如果不是,它們總是傳回 $timeleft
等於提供的 $timeout
。
您可以這樣執行 250 毫秒的睡眠
select(undef, undef, undef, 0.25);
請注意,是否 select
在訊號(例如 SIGALRM)後重新啟動取決於實作。另請參閱 perlport 以取得 select
可攜性的注意事項。
發生錯誤時,select
的行為就像 select(2):它傳回 -1
並設定 $!
。
在某些 Unix 上,select(2) 即使在沒有資料可用的情況下,也可能會回報一個 socket 檔案描述符為「準備讀取」,因此任何後續的 read
都會被封鎖。如果您始終在 socket 上使用 O_NONBLOCK
,則可以避免這種情況。請參閱 select(2) 和 fcntl(2) 以取得進一步的詳細資訊。
標準 IO::Select
模組提供一個對 select
來說更友善的使用者介面,主要是因為它為您執行所有位元遮罩的工作。
警告:不應嘗試將緩衝 I/O(例如 read
或 readline
)與 select
混合使用,除非 POSIX 允許,即使在這種情況下也只限於 POSIX 系統。您必須改用 sysread
。
可攜性問題:"select" in perlport。