IO::Handle Reference
Opened file or stream
What it is #
class IO::Handle { }
Position in the hierarchy #
| Inherits from | — |
| Does | — |
| Inherited by | IO::CatHandle, IO::Pipe |
Routines #
Signatures are reproduced from the documentation, including their declared return types. A routine listed here is part of the type's published interface; whether Raku++ implements it is a separate question, answered by the examples below.
method open #
method open(IO::Handle:D:
Opens the handle in one of the modes. Fails with appropriate exception if the open fails. See description of individual methods for the accepted values and behavior of :$chomp, :$nl-in, :$nl-out, and :$enc. The values for parameters default
method comb #
method comb(IO::Handle:D: Bool :$close, |args --> Seq:D)
Returns Seq:D.
Read the handle and processes its contents the same way Str.comb does, taking the same arguments, closing the handle when done if $close is set to a true value. Implementations may slurp the file in its entirety when this method is called. Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.
method chomp #
One of the attributes that can be set via .new or open. Defaults to True. Takes a Bool specifying whether the line separators (as defined by .nl-in) should be removed from content when using .get or .lines methods.
routine get #
method get(IO::Handle:D: --> Str:D)
multi get (IO::Handle $fh = $*ARGFILES --> Str:D)
Returns Str:D.
Reads a single line of input from the handle, removing the trailing newline characters (as set by .nl-in) if the handle's .chomp attribute is set to True. Returns Nil, if no more input is available. The subroutine form defaults to $*ARGFILES if no handle is given. Attempting to call this method when the handle is
routine getc #
method getc(IO::Handle:D: --> Str:D)
multi getc (IO::Handle $fh = $*ARGFILES --> Str:D)
Returns Str:D.
Reads a single character from the input stream. Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown. The subroutine form defaults to $*ARGFILES if no handle is given. Returns Nil, if no more input is available, otherwise
submethod DESTROY #
submethod DESTROY(IO::Handle:D:)
Closes the filehandle, unless its native-descriptor is 2 or lower. This ensures the standard filehandles do not get inadvertently closed. Note that garbage collection is not guaranteed to happen, so you must NOT rely on DESTROY for closing the handles you write to and instead close them yourself. Programs that open a lot of files should close the handles explicitly
method gist #
method gist(IO::Handle:D: --> Str:D)
Returns Str:D.
Returns a string containing information which .path, if any, the handle is created for and whether it is .opened.
method eof #
method eof(IO::Handle:D: --> Bool:D)
Returns Bool:D.
Non-blocking. Returns True if the read operations have exhausted the contents of the handle. For seekable handles, this means current position is at or beyond the end of file and seeking an exhausted handle back into the file's contents will result in eof returning False again. On non-seekable handles and handles opened to zero-size
method encoding #
multi method encoding(IO::Handle:D: --> Str:D)
multi method encoding(IO::Handle:D: $enc --> Str:D)
Returns Str:D.
Returns a Str representing the encoding currently used by the handle, defaulting to "utf8". Nil indicates the filehandle is currently in binary mode. Specifying an optional positional $enc argument switches the encoding used by the handle; specify Nil as encoding to put the handle into binary mode. The accepted values for encoding are case-insensitive. The available encodings
routine lines #
sub lines( $what = $*ARGFILES, |c)
multi method lines( IO::Handle:D: $limit, :$close )
multi method lines( IO::Handle:D: :$close )
The sub form, which takes $*ARGFILES by default, will apply the lines method to the object that's the first argument, and pass it the rest of the arguments. The method will return a Seq each element of which is a line from the handle (that is chunks delineated by .nl-in). If the handle's .chomp attribute is set to True,
method lock #
method lock(IO::Handle:D:
Places an advisory lock on the file the filehandle if open for. If :$non-blocking is True will fail with X::IO::Lock if lock could not be obtained, otherwise will block until the lock can be placed. If :$shared is True will place a shared (read) lock, otherwise will place an exclusive (write) lock. On success, returns True; fails with X::IO::Lock if lock cannot be placed (e.g. when
method unlock #
method unlock(IO::Handle:D: --> True)
Returns True.
Removes a lock from the filehandle. It will return True or fail with an exception if it's not possible.
routine words #
multi words(IO::Handle:D $fh = $*ARGFILES, $limit = Inf, :$close --> Seq:D)
multi method words(IO::Handle:D: $limit = Inf, :$close --> Seq:D)
Returns Seq:D.
Similar to Str.words, separates the handle's stream on contiguous chunks of whitespace (as defined by Unicode) and returns a Seq of the resultant "words." Takes an optional $limit argument that can be a non-negative Int, Inf, or Whatever (which is interpreted to mean Inf), to indicate only up-to $limit words
method split #
method split(IO::Handle:D: :$close, |c)
Slurps the handle's content and calls Str.split on it, forwarding any of the given arguments. If :$close named parameter is set to True, will close the invocant after slurping. Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode
method spurt #
multi method spurt(IO::Handle:D: Blob $data, :$close = False)
multi method spurt(IO::Handle:D: Cool $data, :$close = False)
Writes all of the $data into the filehandle, closing it when finished, if $close is True. For Cool $data, will use the encoding the handle is set to use (IO::Handle.open or IO::Handle.encoding). Behavior for spurting a Cool when the handle is in binary mode or spurting a Blob when the handle is NOT in binary
method print #
multi method print(**@text --> True)
multi method print(Junction:D --> True)
Returns True.
Writes the given @text to the handle, coercing any non-Str objects to Str by calling .Str method on them. Junction arguments autothread and the order of printed strings is not guaranteed. See write to write bytes. Attempting to call this method when the handle is in binary mode will result in
method print-nl #
method print-nl(IO::Handle:D: --> True)
Returns True.
Writes the value of $.nl-out attribute into the handle. This attribute, by default, is , but see the page on newline for the rules it follows in different platforms and environments. Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.
method printf #
multi method printf(IO::Handle:D: Cool $format, *@args)
Formats a string based on the given format and arguments and .prints the result into the filehandle. See sprintf for details on acceptable format directives. Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.
method out-buffer #
method out-buffer(--> Int:D) is rw
Returns Int:D.
Controls output buffering and can be set via an argument to open. Takes an int as the size of the buffer to use (zero is acceptable). Can take a Bool: True means to use default, implementation-defined buffer size; False means to disable buffering (equivalent to using 0 as buffer size). Lastly, can take a Nil to enable TTY-based buffering control: if
method put #
multi method put(**@text --> True)
multi method put(Junction:D --> True)
Returns True.
Writes the given @text to the handle, coercing any non-Str objects to Str by calling .Str method on them, and appending the value of .nl-out at the end. Junction arguments autothread and the order of printed strings is not guaranteed. Attempting to call this method when the handle is
method say #
multi method say(IO::Handle:D: **@text --> True)
Returns True.
This method is identical to put except that it stringifies its arguments by calling .gist instead of .Str. Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.
method read #
method read(IO::Handle:D: Int(Cool:D) $bytes = 65536 --> Buf:D)
Returns Buf:D.
Binary reading; reads and returns up to $bytes bytes from the filehandle. $bytes defaults to an implementation-specific value (in Rakudo, the value of $*DEFAULT-READ-ELEMS, which by default is set to 65536). This method can be called even when the handle is not in binary mode.
method readchars #
method readchars(IO::Handle:D: Int(Cool:D) $chars = 65536 --> Str:D)
Returns Str:D.
Reading chars; reads and returns up to $chars chars (graphemes) from the filehandle. $chars defaults to an implementation-specific value (in Rakudo, the value of $*DEFAULT-READ-ELEMS, which by default is set to 65536). Attempting to call this method when the handle is in binary mode will result in X::IO::BinaryMode exception being thrown.
method write #
method write(IO::Handle:D: Blob:D $buf --> True)
Returns True.
Writes $buf to the filehandle. This method can be called even when the handle is not in binary mode.
method seek #
method seek(IO::Handle:D: Int:D $offset, SeekType:D $whence --> True)
Returns True.
Move the file pointer (that is, the position at which any subsequent read or write operations will begin) to the byte position specified by $offset relative to the location specified by $whence which may be one of: a negative offset if you want to position before the end of the file.
method tell #
method tell(IO::Handle:D: --> Int:D)
Returns Int:D.
Return the current position of the file pointer in bytes.
method slurp-rest #
multi method slurp-rest(IO::Handle:D: :$bin! --> Buf)
multi method slurp-rest(IO::Handle:D: :$enc --> Str)
Returns Buf or Str.
DEPRECATION NOTICE: this method is deprecated in the 6.d version. Do not use it for new code, use .slurp method instead. Returns the remaining content of the file from the current file position (which may have been set by previous reads or by seek.) If the adverb :bin is provided a Buf will be returned; otherwise the return will be a Str with
method slurp #
method slurp(IO::Handle:D: :$close, :$bin)
Returns all the content from the current file pointer to the end. If the invocant is in binary mode or if $bin is set to True, will return a Buf, otherwise will decode the content using invocant's current .encoding and return a Str. If :$close is set to True, will close the handle when finished reading. Note: On Rakudo this method was introduced
method Supply #
multi method Supply(IO::Handle:D: :$size = 65536)
Returns a Supply that will emit the contents of the handle in chunks. The chunks will be Buf if the handle is in binary mode or, if it isn't, Str decoded using same encoding as IO::Handle.encoding. The size of the chunks is determined by the optional :size named parameter and 65536 bytes in binary mode or 65536 characters in non-binary
method path #
method path(IO::Handle:D:)
For a handle opened on a file this returns the IO::Path that represents the file. For the standard I/O handles $*IN, $*OUT, and $*ERR it returns an IO::Special object.
method IO #
method IO(IO::Handle:D:)
Alias for .path
method Str #
Returns the value of .path, coerced to Str.
routine close #
method close(IO::Handle:D: --> Bool:D)
multi close(IO::Handle $fh)
Returns Bool:D.
Closes an open filehandle, returning True on success. No error is thrown if the filehandle is already closed, although if you close one of the standard filehandles (by default: $*IN, $*OUT, or $*ERR: any handle with native-descriptor 2 or lower), you won't be able to re-open them. It's a common idiom to use LEAVE phaser for closing the handles, which ensures the handle is closed regardless of how the
method flush #
method flush(IO::Handle:D: --> True)
Returns True.
Will flush the handle, writing any of the buffered data. Returns True on success; otherwise, fails with X::IO::Flush.
method native-descriptor #
method native-descriptor(IO::Handle:D:)
This returns a value that the operating system would understand as a "file descriptor" and is suitable for passing to a native function that requires a file descriptor as an argument such as fcntl or ioctl.
method nl-in #
method nl-in(--> Str:D) is rw
Returns Str:D.
One of the attributes that can be set via .new or open. Defaults to ["\x0A", "\r\n"]. Takes either a Str or Array of Str specifying input line ending(s) for this handle. If .chomp attribute is set to True, will strip these endings in routines that chomp, such as get and lines.
method nl-out #
One of the attributes that can be set via .new or open. Defaults to "\n". Takes a Str specifying output line ending for this handle, to be used by methods .put and .say.
method opened #
method opened(IO::Handle:D: --> Bool:D)
Returns Bool:D.
Returns True if the handle is open, False otherwise.
method t #
method t(IO::Handle:D: --> Bool:D)
Returns Bool:D.
Returns True if the handle is opened to a TTY, False otherwise. As of 6.d language (early implementation available in Rakudo compiler release 2018.08), a few helper methods are available to simplify creation of custom IO::Handle objects. In your subclass you simply need to implement those methods to affect all of the related features. If your handle wants
method WRITE #
method WRITE(IO::Handle:D: Blob:D \data --> Bool:D)
Returns Bool:D.
Called whenever a write operation is performed on the handle. Always receives the data as a Blob, even if a textual writing method has been called. In this example we are creating a simple WRITE redirection which stores anything written to the filehandle to an array. We need to save the standard output first, which we do in $output, and then everything that is printed or said (through say) gets stored in the defined IO::Store class. Two
method READ #
method READ(IO::Handle:D: Int:D \bytes --> Buf:D)
Returns 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
method EOF #
method EOF(IO::Handle:D: --> Bool:D)
Returns Bool:D.
Indicates whether "end of file" has been reached for the data source of the handle; i.e. no more data can be obtained by calling .READ method. Note that this is not the same as eof method, which will return True only if .EOF returns True and all the decoder buffers, if any were used by the handle, are also empty. See .READ for an example implementation.
Examples, run three ways #
Every example below comes from the official documentation, together with the output that documentation asserts. Each was then executed by Rakudo and by Raku++ when this page was built. Where the three agree, one result is shown; where they do not, all three are — because which of them is wrong is exactly the information worth having.
4 all-differ · 1 doc-drift · 25 no-output · 1 not-runnable · 2 ok · 4 rakupp-differs
my $fh = '/tmp/log.txt'.IO.open; say $fh.^name; # OUTPUT: IO::Handle
Not executed: the documentation states no expected output for this example.
my $fh = IO::Handle.new( :path( '/tmp/log.txt'.IO.path ) ).open;
Not executed: the documentation states no expected output for this example.
:$r, :$w, :$x, :$a, :$update, :$rw, :$rx, :$ra, :$mode is copy, :$create is copy, :$append is copy, :$truncate is copy, :$exclusive is copy, :$bin, :$enc is copy, :$chomp = $!chomp, :$nl-in is copy = $!nl-in, Str:D :$nl-out is copy = $!nl-out, :$out-buffer is copy, )
Not executed: the documentation states no expected output for this example.
:r same as specifying :mode<ro> same as specifying nothing :w same as specifying :mode<wo>, :create, :truncate :a same as specifying :mode<wo>, :create, :append :x same as specifying :mode<wo>, :create, :exclusive :update same as specifying :mode<rw> :rw same as specifying :mode<rw>, :create :ra same as specifying :mode<rw>, :create, :append :rx same as specifying :mode<rw>, :create, :exclusive
Not executed: the documentation states no expected output for this example.
:mode<ro> means "read only" :mode<wo> means "write only" :mode<rw> means "read and write" :create means the file will be created, if it does not exist :truncate means the file will be emptied, if it exists :exclusive means .open will fail if the file already exists :append means writes will be done at the end of file's current contents
Not executed: the documentation states no expected output for this example.
my $fh = 'path/to/file'.IO.open;
say "The file has {+$fh.comb: '♥', :close} ♥s in it";Not executed: the documentation states no expected output for this example.
has $.chomp is rw = True
Not executed: the documentation states no expected output for this example.
$*IN.get.say; # Read one line from the standard input my $fh = open 'filename'; $fh.get.say; # Read one line from a file $fh.close; say get; # Read one line from $*ARGFILES
Not executed: the documentation states no expected output for this example.
say IO::Handle.new; # IO::Handle<(Any)>(closed) say "foo".IO.open; # IO::Handle<"foo".IO>(opened)
Not executed: the documentation states no expected output for this example.
=begin code :lang<shell>
$ echo "x" | raku -e 'with $*IN { .read: 10000; .eof.say; .read: 10; .eof.say }'
False
True
=end codeNot executed: the documentation states no expected output for this example.
utf8 utf16 utf16le utf16be utf8-c8 iso-8859-1 windows-1251 windows-1252 windows-932 ascii
Not executed: the documentation states no expected output for this example.
with 'foo'.IO {
.spurt: "First line is text, then:\nBinary";
my $fh will leave {.close} = .open;
$fh.get.say; # OUTPUT: «First line is text, then:»
$fh.encoding: Nil;
$fh.slurp.say; # OUTPUT: «Buf[uint8]:0x<42 69 6e 61 72 79>»
}First line is text, then:
Buf[uint8]:0x<42 69 6e 61 72 79>
First line is text, then:
Buf[uint8]:0x<42 69 6E 61 72 79>
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.
say "The file contains ", '50GB-file'.IO.open.lines.grep(*.contains: 'Raku').elems, " lines that mention Raku"; # OUTPUT: «The file contains 72 lines that mention Raku»
The file contains 72 lines that mention Raku
The file contains 0 lines that mention Raku
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.
say lines( "/proc/$*PID/statm".IO ); # OUTPUT: «(58455 31863 8304 2 0 29705 0)»
Neither engine can run this in isolation — the example depends on context from the surrounding text.
Bool:D :$non-blocking = False, Bool:D :$shared = False
--> True)Not executed: the documentation states no expected output for this example.
# One program writes, the other reads, and thanks to locks either
# will wait for the other to finish before proceeding to read/write
# Writer
given "foo".IO.open(:w) {
.lock;
.spurt: "I ♥ Raku!";
.close; # closing the handle unlocks it; we could also use `unlock` for that
}
# Reader
given "foo".IO.open {
.lock: :shared;
.slurp.say; # OUTPUT: «I ♥ Raku!»
.close;
}I ♥ Raku!
Documentation, Rakudo and Raku++ all agree.
my %dict := bag $*IN.words; say "Most common words: ", %dict.sort(-*.value).head: 5;
Not executed: the documentation states no expected output for this example.
my $fh = 'path/to/file'.IO.open; $fh.split: '♥', :close; # Returns file content split on ♥
Not executed: the documentation states no expected output for this example.
my $fh = 'path/to/file'.IO.open: :w; $fh.print: 'some text'; $fh.close;
Not executed: the documentation states no expected output for this example.
my $fh = 'path/to/file'.IO.open: :w, :nl-out("\r\n");
$fh.print: "some text";
$fh.print-nl; # prints \r\n
$fh.close;Not executed: the documentation states no expected output for this example.
my $fh = open 'path/to/file', :w; $fh.printf: "The value is %d\n", 32; $fh.close;
Not executed: the documentation states no expected output for this example.
given 'foo'.IO.open: :w, :1000out-buffer {
.say: 'Hello world!'; # buffered
.out-buffer = 42; # buffer resized; previous print flushed
.say: 'And goodbye';
.close; # closing the handle flushes the buffer
}Not executed: the documentation states no expected output for this example.
my $fh = 'path/to/file'.IO.open: :w; $fh.put: 'some text'; $fh.close;
Not executed: the documentation states no expected output for this example.
my $fh = open 'path/to/file', :w; $fh.say(Complex.new(3, 4)); # OUTPUT: «3+4i» $fh.close;
3+4i
Both engines agree; the documentation states something else. Trust the engines.
(my $file = 'foo'.IO).spurt: 'I ♥ Raku';
given $file.open {
say .read: 6; # OUTPUT: «Buf[uint8]:0x<49 20 e2 99 a5 20>»
.close;
}Buf[uint8]:0x<49 20 e2 99 a5 20>
Buf[uint8]:0x<49 20 E2 99 A5 20>
Buf:0x<49 20 E2 99 A5 20>
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.
(my $file = 'foo'.IO).spurt: 'I ♥ Raku';
given $file.open {
say .readchars: 5; # OUTPUT: «I ♥ R»
.close;
}I ♥ R
Documentation, Rakudo and Raku++ all agree.
"foo".IO.open(:bin).Supply(:size<10>).tap: *.raku.say; # OUTPUT: # Buf[uint8].new(73,32,226,153,165,32,80,101,114,108) # Buf[uint8].new(32,54,33,10) "foo".IO.open.Supply(:size<10>).tap: *.raku.say; # OUTPUT: # "I ♥ Perl" # " 6!\n"
Not executed: the documentation states no expected output for this example.
say "foo".IO.open.Str; # OUTPUT: «foo»
foo
foo
buffer
mode r
path foo
Raku++ disagrees with both the documentation and Rakudo — a defect.
given "foo/bar".IO.open(:w) {
.spurt: "I ♥ Raku!";
.close;
}Not executed: the documentation states no expected output for this example.
do {
my $fh = open "path-to-file";
LEAVE close $fh;
# ... do stuff with the file
}
sub do-stuff-with-the-file (IO $path-to-file) {
my $fh = $path-to-file.open;
# stick a `try` on it, since this will get run even when the sub is
# called with wrong arguments, in which case the `$fh` will be an `Any`
LEAVE try close $fh;
# ... do stuff with the file
}Not executed: the documentation states no expected output for this example.
given "foo".IO.open: :w {
LEAVE .close;
.print: 'something';
'foo'.IO.slurp.say; # (if the data got buffered) OUTPUT: «»
.flush; # flush the handle
'foo'.IO.slurp.say; # OUTPUT: «something»
}something
something
something
All three differ. Needs a human.
Not yet examined. Which of these is correct has not been established — do not treat either engine as settled here.
with 'test'.IO {
.spurt: '1foo2bar3foo'; # write some data into our test file
my $fh will leave {.close} = .open; # can also set .nl-in via .open arg
$fh.nl-in = [<foo bar>]; # set two possible line endings to use;
$fh.lines.say; # OUTPUT: ("1", "2", "3").Seq
}Not executed: the documentation states no expected output for this example.
has Str:D $.nl-out is rw = "\n";
Not executed: the documentation states no expected output for this example.
with 'test'.IO {
given .open: :w {
.put: 42;
.nl-out = 'foo';
.put: 42;
.close;
}
.slurp.raku.say; # OUTPUT: «"42\n42foo"»
}"42\n42foo"
"42\n42foo"
buffer
mode w
path test
buffer
mode w
nl-out foo
path test
""
Raku++ disagrees with both the documentation and Rakudo — a defect.
class IO::URL is IO::Handle {
has $.URL is required;
has Buf $!content;
submethod TWEAK {
use WWW; # ecosystem module that will let us `get` a web page
use DOM::Tiny; # ecosystem module that will parse out all text from HTML
$!content := Buf.new: DOM::Tiny.parse(get $!URL).all-text(:trim).encode;
self.encoding: 'utf8'; # set up encoder/decoder
}
method open(|) { self } # block out some IO::Handle methods
method close(|) { self } # that work with normal low-level file
method opened { ! self.EOF } # handles, since we don't. This isn't
method lock(| --> True) { } # necessary, but will make our handle
method unlock( --> True) { } # be more well-behaved if someone
# actually calls one of these methods. There are more of these you
# can handle, such as .tell, .seek, .flush, .native-descriptor, etc.
method WRITE(|) {
# For this handle we'll just die on write. If yours can handle writes.
# The data to write will be given as a Blob positional argument.
die "Cannot write into IO::URL";
}
method READ(\bytes) {
# We splice off the requested number of bytes from the head of
# our content Buf. The handle's decoder will handle decoding them
# automatically, if textual read methods were called on the handle.
$!content.splice: 0, bytes
}
method EOF {
# For "end of file", we'll simply report whether we still have
# any bytes of the website we fetched on creation.
not $!content
}
}
my $fh := IO::URL.new: :URL<raku.org>;
# .slurp and print all the content from the website. We can use all other
# read methods, such as .lines, or .get, or .readchars. All of them work
# correctly, even though we only defined .READ and .EOF
$fh.slurp.say;Not executed: the documentation states no expected output for this example.
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.decode();
True;
}
method gist() {
return @!lines.join("\n" );
}
}
my $store = IO::Store.new();
my $output = $PROCESS::OUT;
$PROCESS::OUT = $store;
.say for <one two three>;
$PROCESS::OUT = $output;
say $store.lines(); # OUTPUT: «[one two three]»[one
two
three
][one
two
three
]
Raku++ disagrees with both the documentation and Rakudo — a defect.
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»one
two
one
two
Raku++ disagrees with both the documentation and Rakudo — a defect.