In IO::Handle§
See primary documentation in context for method READ
method READ(IO::Handle:D: Int:D \bytes --> Buf:D)
Called whenever a read operation is performed on the handle. Receives the number of bytes requested to read. Returns a Buf
with those bytes which can be used to either fill the decoder buffer or returned from reading methods directly. The result is allowed to have fewer than the requested number of bytes, including no bytes at all.
If you provide your own .READ
, you very likely need to provide your own .EOF
as well, for all the features to behave correctly.
The compiler may call .EOF
method any number of times during a read operation to ascertain whether a call to .READ
should be made. More bytes than necessary to satisfy a read operation may be requested from .READ
, in which case the extra data may be buffered by the IO::Handle
or the decoder it's using, to fulfill any subsequent reading operations, without necessarily having to make another .READ
call.
class IO::Store is IO::Handle { has @.lines = []; submethod TWEAK { self.encoding: 'utf8'; # set up encoder/decoder } method WRITE(IO::Handle:D: Blob:D \data --> Bool:D) { @!lines.push: data; True; } method whole() { my Buf $everything = Buf.new(); for @!lines -> $b { $everything ~= $b; } return $everything; } method READ(IO::Handle:D: Int:D \bytes --> Buf:D) { my Buf $everything := self.whole(); return $everything; } method EOF { my $everything = self.whole(); !$everything; } } my $store := IO::Store.new(); $store.print( $_ ) for <one two three>; say $store.read(3).decode; # OUTPUT: «one» say $store.read(3).decode; # OUTPUT: «two»
In this case, we have programmed the two READ
and EOF
methods, as well as WRITE
, which stores every line in an element in an array. The read
method actually calls READ
, returning 3 bytes, which correspond to the three characters in the first two elements. Please note that it's the IO::Handle
base class the one that is taking care of cursor, since READ
just provides a handle into the whole content of the object; the base class will READ
1024 * 1024 bytes at a time. If your object is planned to hold an amount of bytes bigger than that, you will have to handle an internal cursor yourself. That is why in this example we don't actually use the bytes
argument.