我可以使用两种方式本地化$|
,还是应该使用一种方式来支持另一方?
方法1:在“_init_scr”中备份$|
的旧值,并在调用“_end_win”时将$|
设置为旧值。
方式2:在调用“_init_scr”之后调用local $| = 1
。
package Package_name
# ...
sub _init_scr {
my ( $arg ) = @_;
$arg->{old_handle} = select( $arg->{handle_out} );
#$arg->{backup_flush} = $|; # way 1
$| = 1;
# ...
}
sub _end_win {
my ( $arg ) = @_;
# ...
#$| = $arg->{backup_flush}; # way 1
select( $arg->{old_handle} );
}
sub choose {
my $arg = ...;
# ...
_init_scr( $arg );
# way 2 - instead of setting `$|` in "_init_scr" set it here:
#local $| = 1;
# ...
while ( 1 ) {
my $c = _getch( $arg );
# ...;
given ( $c ) {
# ...
when ( $c == CONTROL_C ) {
_end_win( $arg );
print "^C";
kill( 'INT', $$ );
return;
}
when ( $c == KEY_ENTER ) {
# ...
_end_win( $arg );
return $result;
}
}
}
}
答案 0 :(得分:3)
使用local
。这样,无论退出子如何(例外,早期$|
等),return
都会被恢复。
顺便说一下,您可以使用select()->flush;
而不是来回切换$|
。
use IO::Handle qw( ); # Required in older versions of Perl.
print "^C";
select()->flush();
尽管如此,local $|
的优势已经消失,因为无论如何你都需要打电话给_end_win
进行清理。因此,让我们摆脱_end_win
的需要。
use Sub::ScopeFinalizer qw( scope_finalizer );
sub _local_scr {
my ( $arg ) = @_;
my $old_autoflush = $|;
my $old_handle = select( $arg->{handle_out} );
$| = 1;
return scope_finalizer {
$| = $old_autoflush;
select($old_handle);
};
}
sub choose {
my $arg = ...;
my $guard = _local_scr( $arg );
while ( 1 ) {
...
print "^C";
kill( 'INT', $$ );
return;
...
}
}
答案 1 :(得分:2)
如果要本地化值,只需使用local
即可。当您的本地化范围退出时,它将处理恢复原始值,而无需您做任何额外的努力(或错误的机会)。
答案 2 :(得分:2)
第三种方式:
use IO::Handle;
# ...
$arg->{handle_out}->autoflush(1);
# ...
$arg->{handle_out}->autoflush(0);
IO :: Handle中有各种其他方便的方法。
答案 3 :(得分:1)
你应该使用local $| = 1;
,因为这是Perl的惯用方法。它比跟踪另一个变量中的值更简单。
使用一组额外的大括号(如果需要)来创建一个范围,以便它只适用于应该设置它的程序部分。
{
#Buffering is turned off only in here.
local $| = 1;
unbuffered_commands();
}
buffered_commands();