Perl 6 $ * ARGFILES.handles в бинарном режиме? - PullRequest
0 голосов
/ 05 декабря 2018

Я пробую $ * ARGFILES.handles, и кажется, что он открывает файлы в двоичном режиме.

Я пишу программу zip-merge, которая печатает одну строку из каждого файла до тех пор, покабольше нет строк для чтения.

#! /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

Сбой при: Невозможно выполнить 'get' для дескриптора в двоичном режиме в блоке в ./zip-merge строка 7

Указанные файлы представляют собой текстовые файлы (закодированные в utf8), и я получаю сообщение об ошибке как для неисполняемых, так и для исполняемых файлов (с кодом perl6).

Закомментированная строка говорит utf8 для каждого файла, который я ему даю, поэтому они не должны быть двоичными,

perl6 -v: Это версия Rakudo 2018.10, построенная на версии MoarVM 2018.10

Я что-то сделал?неправильно или я обнаружил ошибку?

Ответы [ 2 ]

0 голосов
/ 06 декабря 2018

Объекты IO :: Handle, возвращаемые .handles, закрыты.

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
0 голосов
/ 05 декабря 2018

:bin равен , всегда установленному для объектов этого типа .Поскольку вы работаете с дескрипторами, вы должны либо читать построчно, как указано в примере, либо сбрасывать дескриптор, чтобы он не находился в двоичном режиме.

...