2016-01-20 98 views
5

我该如何在Perl6中编写这个Perl5代码?Perl6:如何读取STDIN原始数据?

my $return = binmode STDIN, ':raw'; 
if ($return) { 
    print "\e[?1003h"; 
} 

评论到cuonglm的答案。

我已经使用read

my $termios := Term::termios.new(fd => 1).getattr; 
$termios.makeraw; 
$termios.setattr(:DRAIN); 

sub ReadKey { 
    return $*IN.read(1).decode(); 
} 

sub mouse_action { 
    my $c1 = ReadKey(); 
    return if ! $c1.defined; 
    if $c1 eq "\e" { 
     my $c2 = ReadKey(); 
     return if ! $c2.defined; 
     if $c2 eq '[' { 
      my $c3 = ReadKey(); 
      if $c3 eq 'M' { 
       my $event_type = ReadKey().ord - 32; 
       my $x   = ReadKey().ord - 32; 
       my $y   = ReadKey().ord - 32; 
       return [ $event_type, $x, $y ]; 
      } 
     } 
    } 
} 

但随着STDIN设置为UTF-8我得到的错误与$x$y大于127 - 32:

Malformed UTF-8 at ... 
+0

utf-8是一种非二进制安全的可变长度编码;取决于你想要做什么,或者使用'.decode('latin1')',或者只保留数字值并用'$ c3 =='M'替换'$ c3 eq'M''。 ord' – Christoph

+0

我认为你的代码现在不能正常工作的唯一原因是你使用.decode,正如Christoph所建议的那样,你可以使用latin1来获得一个不会失败的字符串,而不管你输入了什么数据。否则,我建议你只要返回$ * IN.read(1)[0]就只获得单字节值。 – timotimo

+0

现在我有三种可能性。我已经尝试过'latin1'解决方案。也许我坚持下去。 –

回答

5

您可以使用method read()class IO::Handle执行二进制读数:

#!/usr/local/bin/perl6 

use v6; 

my $result = $*IN.read(512); 
$*OUT.write($result); 

然后:

$ printf '1\0a\n' | perl6 test.p6 | od -t x1 
0000000 31 00 61 0a 
0000004 

你不需要binmode在Perl 6的,因为当你可以决定读取数据的二进制或文字,取决于你用什么方法。