本地化“$ |”

时间:2013-04-16 14:36:15

标签: perl

我可以使用两种方式本地化$|,还是应该使用一种方式来支持另一方?

方法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;
            }
        }
    }
}

4 个答案:

答案 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();