Skip to content

Commit

Permalink
Final part of S16 rewrite
Browse files Browse the repository at this point in the history
S32/IO to follow soon.
  • Loading branch information
lizmat committed Sep 22, 2014
1 parent 083a1a2 commit e1d9ceb
Showing 1 changed file with 141 additions and 5 deletions.
146 changes: 141 additions & 5 deletions S16-io.pod
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ namespace.

When no explicit filehandle is used, the standard IO operators are
defined in terms of the dynamic variables. So the C<say> function
prints to C<$*OUT>, while C<note> prints to C<$*ERR>. The C<< lines() >>
prints to C<$*OUT>, while C<note> prints to C<$*ERR>. The C<lines()>
term inputs from C<$*ARGFILES> which defaults to C<$*IN> in the absence of any
filenames. So any given dynamic scope (interpreter,
thread, function or method call) may redefine the current meaning of
Expand Down Expand Up @@ -97,11 +97,16 @@ initialized for the current environment. But like any dynamic variable,
can be overridden in a scope:

{ # Win32 path semantics in here
my $*SPEC = IO::Spec::Win32.new;
my $*SPEC = IO::Spec::Win32;
... # your code
}
# original path semantics here again

Please note that it does B<not> need to be an instantiated object: the standard
C<IO::Spec> subclasses only provide class methods, and therefore do not need an
instantiated object. But that could be different for a very specific
third-party implementation of an C<IO::Spec> class.

=head2 $*CWD and chdir()

The dynamic variable $*CWD is an C<IO::Path> object of the current working
Expand Down Expand Up @@ -178,12 +183,12 @@ Of course, it is also possible to specify a specify a specific system's
path semantics module when creating an C<IO::Path> object with the C<:SPEC>
named parameter:

my $SPEC = IO::Spec::Win32.new;
my $SPEC = IO::Spec::Win32;
my $path = $fileonNTFS.IO(:$SPEC);

or:

my $path = $fileonNTFS.IO(:SPEC<Win32>); # auto-expand to IO::Spec::Win32.new
my $path = $fileonNTFS.IO(:SPEC<Win32>); # auto-expand to IO::Spec::Win32

=head2 Functions, Roles and Classes

Expand Down Expand Up @@ -220,6 +225,11 @@ references to S32-setting-library/IO.pod. An overview:

unlink($filename); # remove a file

link($target,$source); # create a hard-link to a file
symlink($target,$source); # create a symbolic link to a file
islink($target); # is the file a symbolic link?
readlink($target); # the destination of the symlink ($source)

=head3 IO::Testable Role

Role to be consumed by both C<IO::Path> as well as C<IO::Handle>.
Expand Down Expand Up @@ -254,14 +264,140 @@ Role to be consumed by both C<IO::Path> as well as C<IO::Handle>.
$io.modified last modified time of $!path of $io
$io.changed last (metadata) changed time of $!path of $io

To allow for easy chaining of file tests, there is an C<.all> method that can
be fed the tests to be tried as a C<Parcel> of strings. The value returned
will be the first non-True value, or the final True value.

say "rwx" if $io.all: <r w x>;

if $io.all(<r w x s>) -> $size {
say "rwx $size bytes";
}

=head3 IO::Spec Class

The C<IO::Spec> itself only has one method: C<select>. It takes an OS
descriptive name (usually something like what C<$*DISTRO.name> gives) and
returns the type object of the appropriate C<IO::Spec> subclass.

my $*SPEC = IO::Spec.select("MSWin32"); # gives IO::Spec::Win32

Such a subclass should provide at least the following methods (in alphabetical
order):

abs2rel convert an absolute path into a relative one
canonpath return a canonical version of the given path
catdir concatenate directories
catpath create a path from volume/directories/filename
curdir the path to the current directory (usually '.')
devnull the path to the bit bucket (on Unixy systems '/dev/null')
is-absolute whether the path is absolute
join create a path from hash with volume/directories/filename
PATH %ENV<PATH> interpreted as paths
rel2abs convert a relative path into an absolute one
rootdir the path to the root directory (on Unixy systems '/')
splitdir split directories
splitpath split a path into volume/directories/filename as Parcel
split split a path into volume/directories/filename in hash
tmpdir path of the first writeable directory for temporary files
updir the path to the path directory (usually '..')

=head3 IO::Path Class

class IO::Path is Cool does IO::FileTestable { }

The official way to create an C<IO::Path> object is with the C<new> method.
Apart from the C<path> positional, it also takes optional C<:SPEC> and
C<CWD> named parameters. The C<.IO> coercer (which takes the same parameters
as C<.new>) is the syntactic sugar that will most likely be used most often.

my $path = $filename.IO; # current $*SPEC/$*CWD
my $path = $filename.IO(:SPEC(*$SPEC)); # specific IO::SPEC
my $path = $filename.IO(:SPEC(*$SPEC), :CWD($*CWD));

which would be the same as:

my $path = IO::Path.new($filename);
my $path = IO::Path.new($filename, :SPEC(*$SPEC));
my $path = IO::Path.new($filename, :SPEC(*$SPEC), :CWD($*CWD));

If you only have filename components to start with, you can also create an
C<IO::Path> object with the C<:volume>, C<:directory> and C<:basename> named
parameters:

my $path = IO::Path.new( :$volume, :$directory, :$basename );

The following methods are also provided (in alphabetical order):

absolute the absolute, canonical path
basename the basename of the path
chdir change $*CWD if directory
child append basename to path, return new object for that
chmod change attributes of path
contents files in path (if dir)
copy create a copy of file
directory the directory part of the absolute path
is-absolute is the (original) path absolute
is-relative is the (original) path relative
lines contents of file as lines
mkdir create directory
open attempt to open file, return IO::Handle
parent remove last portion of path, return new object for that
pred previous logical path, return new object for that
relative the relative path against CWD
resolve follow symlinks to the real path, return new object for that
rmdir remove directory if empty directory
succ next logical path, return new object for that
unlink remove file
volume the volume of the path (if any)
words contents of file as words

=head3 IO::Handle Class

class IO::Path does IO::FileTestable { }
class IO::Handle does IO::FileTestable { }

The C<IO::Handle> object is usually B<not> directly instantiated, but usually
with C<open()> or C<IO::Path.open>. Nonetheless, you B<can> create an
C<IO::Handle> object with just a path:

my $handle = IO::Handle.new($filename);
my $handle = IO::Handle.new($filename, :SPEC(*$SPEC));
my $handle = IO::Handle.new($filename, :SPEC(*$SPEC), :CWD($*CWD));

This does not interact with anything at all and will appear as if the file
has been C<.close>d. The C<.open> method does interact with the file system:

$handle.open; # same as $handle = $filename.IO.open

It either returns True, or a C<Failure> with additional information.

The other methods of the C<IO::Handle> class are only valid B<after> the
C<.open> has been called succesfully:

close close file handle, flush buffers
encoding set/return encoding of file handle
eof file pointer reached end of file
fileno file descriptor (usually a native integer)
flush flush buffers
get get next line from file
getc get next character from file
IO return new IO::Path of path of file
lines return rest of contents of file as lines
opened is the file open?
path return new IO::Path of path of file
print write characters to file
read read bytes from file
say write characters + newline to file
seek move file pointer to given position
slurp return rest of contents of file
t is the file a TTY (as a person looking?)
tell return position of file pointer
words return rest of contents of file as words
write write bytes to file

=head3 Interplay between Roles and Classes

These classes and roles may cache and share pertinent information for better
performance.

=for vim:set expandtab sw=4:

0 comments on commit e1d9ceb

Please sign in to comment.