select FILEHANDLE
select

傳回目前選取的檔案控制代號。如果提供 FILEHANDLE,則設定新的預設目前輸出檔案控制代號。這有兩個影響:首先,沒有檔案控制代號的 writeprintsay 會預設為此 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 RBITS,WBITS,EBITS,TIMEOUT

這會呼叫 select(2) 系統呼叫,並使用指定的位元遮罩,可以使用 filenovec 沿著這些行來建構

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(例如 readreadline)與 select 混合使用,除非 POSIX 允許,即使在這種情況下也只限於 POSIX 系統。您必須改用 sysread

可攜性問題:"select" in perlport