Perl 6 $ * ARGFILES.handles是二进制模式吗?

时间:2018-12-05 19:52:47

标签: perl6

我正在尝试$ * ARGFILES.handles,看来它以二进制模式打开文件。

我正在编写一个zip合并程序,该程序从每个文件打印一行,直到没有更多行可供读取。

#! /usr/bin/env perl6

my @handles = $*ARGFILES.handles;

# say $_.encoding for @handles;

while @handles
{
  my $handle = @handles.shift;
  say $handle.get;
  @handles.push($handle) unless $handle.eof;
}

我这样调用它:zip-merge person-say3 repeat repeat2

它失败并出现:无法在./zip-merge第7行的块中以二进制模式在句柄上“获取”

指定的文件是文本文件(以utf8编码),并且我收到有关非可执行文件和可执行文件(带有perl6代码)的错误消息。

注释掉的行说我给它的每个文件都是utf8,所以它们不应该是二进制的,

perl6 -v:这是基于MoarVM版本2018.10构建的Rakudo版本2018.10

我做错了什么,还是发现了一个错误?

2 个答案:

答案 0 :(得分:3)

.handles返回的IO :: Handle对象已关闭。

my @*ARGS = 'test.p6';
my @handles = $*ARGFILES.handles;
for @handles { say $_ }
# IO::Handle<"test.p6".IO>(closed)

如果只想让代码正常工作,请在分配给@handles后添加以下行。

.open for @handles;

这样做的原因是.handles的迭代器是用IO::CatHandle.next-handle来编写的,它打开当前的句柄,并关闭前一个句柄。
问题在于,在您有机会对其进行任何工作之前,所有这些人都有机会成为当前的句柄和先前的句柄。
(也许.next-handle和/或.handles需要一个:!close参数。)


假设您希望它像roundrobin一样工作,实际上我会这样写:

# /usr/bin/env perl6
use v6.d;

my @handles = $*ARGFILES.handles;

# a sequence of line sequences
my $line-seqs = @handles.map(*.open.lines);
# Seq.new(
#   Seq.new( '# /usr/bin/env perl6', 'use v6.d' ), # first file
#   Seq.new( 'foo', 'bar', 'baz' ),                # second file
# )

for flat roundrobin $line-seqs {
  .say
}

# `roundrobin` without `flat` would give the following result

# ('# /usr/bin/env perl6', 'foo'),
# ('use v6.d', 'bar'),
# ('baz')

如果您将数组用于$line-seqs,则在将值传递给roundrobin之前,需要先对它们进行除等(.<>)。

for flat roundrobin @line-seqs.map(*.<>) {
  .say
}

实际上,我个人更可能写类似(长)单线的东西。

$*ARGFILES.handles.eager».open».lines.&roundrobin.flat.map: *.put

答案 1 :(得分:1)

:binalways set in this type of objects。由于您正在使用手柄,因此您应该按照示例中的说明逐行阅读,或者重置手柄以使其不处于二进制模式。