Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

for $fh.read(1024) -> $blob #5016

Closed
p6rt opened this issue Jan 7, 2016 · 5 comments
Closed

for $fh.read(1024) -> $blob #5016

p6rt opened this issue Jan 7, 2016 · 5 comments
Labels

Comments

@p6rt
Copy link

p6rt commented Jan 7, 2016

Migrated from rt.perl.org#127204 (status was 'rejected')

Searchable as RT127204$

@p6rt
Copy link
Author

p6rt commented Jan 7, 2016

From @pmqs

Given this can be used to walk though a file

  for $fh.lines -> $line

I assumed I would be able to iterate through a file using "read" like this

my $filename = "/tmp/readtest";
spurt $filename, "abcdefg";

my $fh = open($filename, :r, :bin);

for $fh.read(1024) -> $block { say $block }

Actual output is

97
98
99
100
101
102
103

Alternative is to use

while $fh.read(1024) -> $block { say $block }

IRC Dialog

<TimToady> I think used to force a binary interpretation of a filehandle, but maybe that broke
<TimToady> *read used to

<TimToady> m​: for ($*IN.read(1024),) -> $block { say $block.WHAT }
<camelia> rakudo-moar ed6ec7​: OUTPUT«(Buf[uint8])␤»
<TimToady> it's calling .list on the buf

@p6rt
Copy link
Author

p6rt commented Sep 21, 2016

From @smls

Unless I'm missing something, there is no bug here.

Here's how each example works​:

  for $fh.lines -> $line { ... }

The .lines method is only called once, and returns a lazy sequence of lines (represented as a Seq object). The `for` loop then iterates this sequence.

  for $fh.read(1024) -> $byte { ... }

The .read method is only called once, and returns a binary buffer (represented as a Buf object). The `for` loop then iterates this buffer. It so happens that iterating a Buf iterates over its bytes, each represented as a number.

  while $fh.read(1024) -> $block { ... }

The .read method is called repeatedly, once for each iteration of the while loop. Each iteration gets a Buf object. The while loop stops when `read` returns an empty Buf (which evaluates to False in boolean context).

@p6rt
Copy link
Author

p6rt commented Sep 21, 2016

The RT System itself - Status changed from 'new' to 'open'

@p6rt
Copy link
Author

p6rt commented Oct 4, 2017

From @zoffixznet

On Thu, 07 Jan 2016 12​:50​:43 -0800, pmqs wrote​:

Given this can be used to walk though a file

for $fh.lines -> $line

I assumed I would be able to iterate through a file using "read" like
this

my $filename = "/tmp/readtest";
spurt $filename, "abcdefg";

my $fh = open($filename, :r, :bin);

for $fh.read(1024) -> $block { say $block }

Actual output is

97
98
99
100
101
102
103

Alternative is to use

while $fh.read(1024) -> $block { say $block }

IRC Dialog

<TimToady> I think used to force a binary interpretation of a
filehandle, but maybe that broke
<TimToady> *read used to

<TimToady> m​: for ($*IN.read(1024),) -> $block { say $block.WHAT }
<camelia> rakudo-moar ed6ec7​: OUTPUT«(Buf[uint8])␤»
<TimToady> it's calling .list on the buf

Thanks for the report, but this is not a bug. .lines returns a Seq object with *all* the lines of the file, while .read reads a chunk (in rakudo, default size is 65536) as a Buf object. Your .lines code then iterates over each line, while the `for...read` code iterates over each element of that Buf object.

If you wanted to get creative, you could construct your own Seq from multiple .read()s or use the .Supply method, but the `while` approach is a more appropriate construct​:

  $ perl6 -e 'with "/tmp/readtest".IO { .spurt​: "abcdefg"; with .open​: :bin -> $fh { for {$fh.read(2)} …^ !+* {.say} } }'
  Buf[uint8]​:0x<61 62>
  Buf[uint8]​:0x<63 64>
  Buf[uint8]​:0x<65 66>
  Buf[uint8]​:0x<67>

  $ perl6 -e 'with "/tmp/readtest".IO { .spurt​: "abcdefg"; with .open​: :bin -> $fh { react whenever $fh.Supply​: :2size { .say } } }'
  Buf[uint8]​:0x<61 62>
  Buf[uint8]​:0x<63 64>
  Buf[uint8]​:0x<65 66>
  Buf[uint8]​:0x<67>

@p6rt
Copy link
Author

p6rt commented Oct 4, 2017

@zoffixznet - Status changed from 'open' to 'rejected'

@p6rt p6rt closed this as completed Oct 4, 2017
@p6rt p6rt added the IO label Jan 5, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

1 participant