=begin pod

=TITLE class IO::Handle

=SUBTITLE Opened file or stream

   class IO::Handle does IO { }

=head1 Methods

=head2 method get

Reads a single line from the input stream (usually the Standard Input or a file).

Read one line from the standard input:

=for code :skip-test
$*IN.get;

Read one line from a file:

=for code :skip-test
my $fh = open 'filename';
my $line = $fh.get;


=head2 method getc

Read a single character from the input stream or return Nil. The operation is blocking
and the stream may be buffered.

=head2 method eof

Returns C<True> if the read operations have exhausted the content of the file.

=head2 method lines

    method lines($limit = Inf)

Return a lazy list of the file's lines read via L<get>, limited to C<$limit> lines.
The new line separator (i.e., C<$*IN.nl-in>) will be excluded.

=for code :skip-test
my @data;
my $data-file = open 'readings.csv';
for $data-file.lines -> $line {
    @data.push($line.split(','))
}

=head2 method words

    method words($count = Inf)

Return a lazy list of the file's words (separated on whitespace), limited
to C<$count> words.

=for code :skip-test
my %dict;
++%dict{$_} for $*IN.words;
say "Most common words: ", %dict.sort(*.value).reverse.[^5];

=head2 method split

    multi method split(IO::Handle:D: :$close = False, :$COMB)
    multi method split(IO::Handle:D: $splitter, :$close = False, :$COMB)

Returns a lazy list of strings found between the splitter, just like C<split>
on strings.

=for code :skip-test
my $fh = open 'path/to/file', :r;
$fn.split(' ', close => True); # Returns file content splitted by a space and closes file;

=head2 method comb

    multi method comb(IO::Handle:D: :$close = False)
    multi method comb(IO::Handle:D: Int:D $size, :$close = False)
    multi method comb(IO::Handle:D: $comber, :$close = False)

Returns a lazy list of strings combed from the handle, just like C<comb>
on strings.

=for code :skip-test
my $fh = open 'path/to/file', :r;
$fn.comb(/A+/); # Comb file contents by a regex.

or

=for code :skip-test
my $fh = open 'path/to/file', :r;
$fn.comb(3, close => True); # Comb file contents by 3 characters and close after.

=head2 method print

    method print(*@text --> Bool)

Text writing; writes the given C<@text> to the filehandle.  See L<write>
to write bytes.

=for code :skip-test
my $fh = open 'path/to/file', :w;
$fh.print("some text\n");
$fh.close;

=head2 method print-nl

    method print-nl(IO::Handle:D: --> True)

Writes a newline to the filehandle. The newline marker, which is stored
in the attribute C<$.nl-out>, defaults to C<\n> unless another marker has
been specified in the call to L<open>.

=for code :skip-test
my $fh = open 'path/to/file', :w, nl-out => "\r\n";
$fh.print("some text");
$fh.print-nl;                                        # \r\n
$fh.close;

=head2 method printf

This method is mostly identical to the C library C<printf> and
sprintf functions.  The only difference between the two functions is
that C<sprintf> returns a string while the C<printf> function writes
to a file.  See L<sub sprintf|https://docs.perl6.org/type/Str#sub_sprintf> for details about
the Perl 6 C<$format> implementation

Note that currently C<printf> is not a method for C<IO::Handle>, but
its effect may be duplicated with a work-around using C<sub sprintf>
and methods C<print> or C<say>.  For example:

=for code :skip-test
my $fh = open 'path/to/file', :w;
$fh.print(sprintf("%d\n", 32));
$fh.close;

The C<say> method (see below) may be used for an automatic ending
newline:

=for code :skip-test
my $fh = open 'path/to/file', :w;
$fh.say(sprintf("%d", 32));
$fh.close;

See L<sub sprintf|https://docs.perl6.org/type/Str#sub_sprintf>
for details about formatting and more examples.

=head2 method say

    method say(IO::Handle:D: |)

This method is identical to L<print|/type/IO::Handle#method_print> except
that it stringifies its arguments by calling C<.gist> on them and
auto-appends a newline, with a call to L<print-nl|/type/IO::Handle#method_print-nl>,
after the final argument.

=for code :skip-test
my $fh = open 'path/to/file', :w;
$fh.say(Complex.new(3, 4));        # 3+4i\n
$fh.close;

=head2 method read

    method read(IO::Handle:D: Int(Cool:D) $bytes --> Blob)

Binary reading; reads and returns up to C<$bytes> bytes from the filehandle.

=head2 method readchars

    method readchars(IO::Handle:D: Int(Cool:D) $chars --> Str)

Reading chars; reads and returns up to C<$chars> chars (graphemes) from the
filehandle.

=head2 method write

    method write(IO::Handle:D: Blob:D $buf)

Binary writing; writes C<$buf> to the filehandle.  See L<print> to write
characters.

=head2 method seek

     method seek(IO::Handle:D: Int:D $offset, SeekType:D $whence --> 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
C<$offset> relative to the location specified by C<$whence> which may be
one of:

=item SeekFromBeginning

The beginning of the file.

=item SeekFromCurrent

The current position in the file.

=item SeekFromEnd

The end of the file.  Please note that you need to specify a negative
offset if you want to position before the end of the file.

=head2 method tell

    method tell(IO::Handle:D: --> Int)

Return the current position of the file pointer in bytes.

=head2 method slurp-rest

    multi method slurp-rest(IO::Handle:D: :$bin!, :$close --> Buf)
    multi method slurp-rest(IO::Handle:D: :$enc, :$close --> Str)

Returns the remaining content of the file from the current file position
(which may have been set by previous reads or by C<seek>.)  If the
adverb C<:bin> is provided a L<Buf> will be returned,
otherwise the return value will be a C<Str> with the optional encoding C<:enc>.
Specifying the adverb C<:close> will cause the filehandle to be closed when
the call has finished.

=for code :skip-test
my $fh = open("content.txt");
my $line = $fh.get;
my $rest-of-file = $fh.slurp-rest(:close);

=head2 method Supply

    multi method Supply(IO::Handle:D: :$size = 65536, :$bin --> Supply)

Returns a C<Supply> that will emit the contents of the handle in chunks.
The size of the chunks is determined by the optional C<:size> named parameter
and defaults to 64K.  The optional C<:bin> named parameter can be specified
to indicate binary reading of the contents, rather than character based
reading.

=head2 method path

For a handle opened on a file this returns the L<IO::Path|/type/IO::Path> that represents
the file. For the standard I/O handles C<$*IN>, C<$*OUT> and C<$*ERR> it returns a
L<IO::Special|/type/IO::Special> object.

=for code :skip-test
$fh.path;

=head2 method close

Will close a previously opened filehandle.

=for code :skip-test
$fh.close;

=head2 method flush

Will flush the filehandle to disk.

=for code :skip-test
$fh.flush;

=head2 method native-descriptor

    method native-descriptor()

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 C<fcntl> or C<ioctl>.

=head2 method opened

    method opened(IO::Handle:D: --> Bool)

Returns C<True> if the handle is open.

=head2 method t

    method t(IO::Handle:D: --> Bool)

Returns C<True> if the handle is opened to a tty.

=head1 Related roles and classes

See also the related role L<IO> and the related class L<IO::Path>.

=end pod

# vim: expandtab shiftwidth=4 ft=perl6
