Perl has three select()
functions with widely differing purposes. One form takes four arguments and is a wrapper around the POSIX select(3)
call. A second form takes zero arguments and returns the currently selected filehandlefile handle: the handle of the output stream used by print
; it normally defaults to standard output. The third form takes one argument, a filehandlefile handle, and makes it the currently selected filehandlefile handle. That is, this form of select()
changes the file that is used by all print
statements (unless they specify their own filehandlefile handle).
Modifying the filehandle file handle used by print
is counterintuitive because subsequent print
statements will no longer print to standard output. Furthermore, the globally selected filehandle file handle is not garbage-collected; it remains open even if the filehandle file handle goes out of scope. Therefore, do not modify the selected filehandle file handle with select()
.
Noncompliant Code Example
...
This compliant solution avoids select()
and directs the print()
statement to use the log filehandle file handle for output.
Code Block | ||||
---|---|---|---|---|
| ||||
sub output_log { my $action = shift; open( my $log, ">>", "log.txt"); ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = localtime(time); $year += 1900; $mon += 1; print $log "$year-$mon-$mday $hour:$min:$sec: $action\n"; } |
...
This noncompliant code example uses the one-argument select()
function temporarily to modify the autoflush property associated with the file. The one-argument select()
returns the old filehandle file handle (normally standard output). After the $log
filehandle file handle is selected, the modification of $|
instructs Perl to autoflush everything sent to the $log
filehandle file handle. That is, every output to the $log
filehandle file handle is flushed immediately. After the modification, select()
is called again to restore the original selected filehandlefile handle.
Code Block | ||||
---|---|---|---|---|
| ||||
select(( select($log), $| = 1)[0]); |
...
Tool | Diagnostic |
---|---|
Perl::Critic | InputOutput::ProhibitOneArgSelect |
Bibliography
...
...