我可以使用这两种方法来本地化$|吗?或者我应该使用其中一种而不是另一种?
方式一:在_init_scr中备份$|的旧值,在调用_end_win时将$|重新设置为旧值。方式二:在调用_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;
}
}
}
}发布于 2013-04-16 22:44:12
使用local。这样,无论sub如何退出(异常、早期return等),$|都会恢复。
顺便说一下,您可以使用select()->flush;而不是来回切换$|。
use IO::Handle qw( ); # Required in older versions of Perl.
print "^C";
select()->flush();也就是说,由于您无论如何都需要调用_end_win来进行清理,所以local $|的优势已经消失。因此,让我们摆脱对_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;
...
}
}发布于 2013-04-16 22:43:14
如果要本地化该值,只需使用local即可。当本地化的作用域退出时,它将处理恢复原始值,而不需要您付出任何额外的努力(或出错的机会)。
发布于 2013-04-16 22:48:35
第三种方法:
use IO::Handle;
# ...
$arg->{handle_out}->autoflush(1);
# ...
$arg->{handle_out}->autoflush(0);在IO::Handle中还有其他各种方便的方法可用。
https://stackoverflow.com/questions/16039907
复制相似问题