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.