=encoding utf8

=head1 NAME

Module::Generic::Scalar::IO - Generic Module Scalar IO Class

=head1 SYNOPSIS

    my $s = Module::Generic::Scalar->new;
    my $io = $s->open || die( $s->error );
    # or
    my $io = Module::Generic::Scalar::IO->new( $scalar_object );

    $io->opened; # Return true if opened or false otherwise
    $io->fileno; # no-op method
    $io->flush; # ditto
    $io->print( <<EOT );
    Mignonne, allons voir si la rose
    Qui ce matin avoit desclose
    Sa robe de pourpre au Soleil,
    A point perdu cette vesprée
    Les plis de sa robe pourprée,
    Et son teint au vostre pareil.
    EOT
    $io->printf( "Author: %s\n", 'Pierre de Ronsard' );
    $io->getc; # return nothing, because we are at the end of file
    $io->eof; # return true if we are at the end of string
    $io->tell; # tells us our position in string
    $io->seek(0,0);
    my $l = $io->getline; # fetch the first line
    $io->seek( $io->length - 1, 0 );
    my $n = $io->write( ', Les Odes', 10 );
    $io->seek(0,0);
    @lines = $io->getlines;
    print $lines[-1], "\n";
    # Returns: Author: Pierre de Ronsard, Les Odes\n

    # The file handle is overloaded, so we can do:
    print "Data is now: $io\n";
    # This will return the content of the string.

    $io->close;

=head1 VERSION

    v0.1.0

=head1 DESCRIPTION

This class L<Module::Generic::Scalar::IO> inherits from L<IO::Scalar> while enable it to use L<Module::Generic::Scalar> objects.

Thus, this makes it possible to use L<Module::Generic::Scalar> object as file handle to print and get data to and from it.

=head1 METHODS

=head2 new

It takes an L<Module::Generic::Scalar> object and calls L</open>. It returns a blessed file handle created by L<IO::Scalar>

=head2 autoflush

This is a no-ope; it does not do anything.

=head binmode

This is a no-ope; it does not do anything.

=head2 clearerr

This is a no-ope; it does not do anything.

=head2 close

This merely untie the scalar. In the L<IO::Scalar>, the scalar reference passed are tied so they can be used in non-object oriented way also.

This method overrides the one from L<IO::Scalar> that would otherwise destroy our underlying L<Module::Generic::Scalar> object.

=head2 eof

Returns true if we are positioned at the end of the string, false otherwise.

=item fileno

This is a no-op that does not do anything.

=head2 flush

This is a no-op that does not do anything.

=head2 getc

Return the next character from our last position, or undef if none remain.

head2 getline

Return the next line, or undef on end of string.

This can only be called in list context, or L<IO::Scalar> will raise an exception.

=head2 getlines

Get all the lines from the position we are in the string.

So using our example in the L</SYNOPSIS> above :

    $io->seek(0,0); # position ourself at the start of the string
    my $c = $io->getc; # get the first character, which is 'M'
    my @lines = $io->getlines;
This will fetch all 6 lines, except the first one will only contain:

    ignonne, allons voir si la rose

i.e. without the leading "M", since L</getc> positioned us after.

SO, be careful about your position in the string.

=head2 object

Returns the underlying L<Module::Generic::Scalar> object.

=head2 open

This takes as its sole argument an L<Module::Generic::Scalar> object

=head2 opened

Returns true if the scalar is opened or false otherwise.

When the filehandle is active, it is L<perlfunc/tied>, so this checks that. Otherwise, it does not do anything else.

=head2 print

This print at the last position in the string the list of data provided.

As of version 2.113 of L<IO::Scalar>, this method merely pushes data at the end of the string without accounting for the last position.

This method corrects this. If you want to make sure you are at the end, do:

    $io->seek(0,2);

=head2 read

    my $buff;
    $io->read( $buff, 1024 );
    # or
    $io->read( $buff, 1024, $offset );

Takes a string as a buffer, a length and an optional offset in the buffer and will attempt to read from our scalar the requested length and place the result in the buffer.

It returns the number of data read at the last position, or C<undef> if there was an error.

=head2 seek

    $io->seek( POSITION, WHENCE );

This takes 2 arguments: an integer representing a position in the string and another integer representing the action to take.

Quoting from L<perlfunc/seek>: "The values for WHENCE are 0 to set the new position *in bytes* to POSITION; 1 to set it to the current position plus POSITION; and 2 to set it to EOF plus POSITION, typically negative."

=head2 sysread

This is an alias for L</read>

=head2 sysseek

This is an alias for L</seek>

=head2 syswrite

This is an alias for L</write>

=head2 tell

Returns the current position in the string.

=head2 truncate

    $io->truncate( $length );
    $io->truncate( $io->tell );

This truncates the string to the specified length C<$length>. It returns true if successful, and false otherwise, such as when at the end of the string.

The position in the string is left unchanged. You may want to call seek before writing to the string.

=head2 write

    $io->write( $data );
    $io->write( $data, 1024 );
    $io->write( $data, 1024, $offset );

This takes some data C<$data>, and optionally some length of those data to take and optionally at a given C<$offset> in C<$data>, and will L</print> those data at the last position in string.

=head1 SEE ALSO

L<Module::Generic::Scalar>, L<IO::Scalar>

=head1 AUTHOR

Jacques Deguest E<lt>F<jack@deguest.jp>E<gt>

=head1 COPYRIGHT & LICENSE

Copyright (c) 2021 DEGUEST Pte. Ltd.

You can use, copy, modify and redistribute this package and associated
files under the same terms as Perl itself.

=cut

