Permalink
Browse files

Merge remote-tracking branch 'origin/io-refactor'

Conflicts:
	S32-setting-library/IO.pod

Still a lot of cleanup to be done, but I hope this is now saner than before,
and the in S32 before the "here be dragons" marker is actually implementable
  • Loading branch information...
2 parents 69be1be + 8db8fd6 commit 261003e6a6065026855eebad3ebccee9a550a57d @moritz moritz committed Jul 14, 2012
Showing with 432 additions and 865 deletions.
  1. +1 −1 S16-io.pod
  2. +2 −0 S32-setting-library/Exception.pod
  3. +429 −864 S32-setting-library/IO.pod
View
2 S16-io.pod
@@ -85,7 +85,7 @@ The use of filenames requires a special quoting syntax. It works as follows:
qp{/path/to/file}
q:p{/path/to/file}
-Both of the above result in the same thing.
+Both of the above result in the same C<IO::Path> object.
The quote characters can be any of the usual ones, although / is probably a bad choice
for filenames.
View
2 S32-setting-library/Exception.pod
@@ -54,6 +54,8 @@ printer.
method gist { "$.message\n$.backtrace" }
method throw() { }
method fail() { }
+ method resumable() { }
+ method resume() { }
}
All direct subclasses are supposed to override method C<message>.
View
1,293 S32-setting-library/IO.pod
@@ -22,8 +22,8 @@ DRAFT: Synopsis 32: Setting Library - IO
Created: 19 Feb 2009 extracted from S29-functions.pod; added stuff from S16-IO later
- Last Modified: 6 July 2012
- Version: 15
+ Last Modified: 14 July 2012
+ Version: 16
The document is a draft.
@@ -32,11 +32,33 @@ repository under
L<https://github.com/perl6/specs/blob/master/S32-setting-library/IO.pod>
so edit it there in the git repository if you would like to make changes.
-=head2 IO
+=head1 Overview
+
+The most common IO operations are C<print> and C<say> for writing and
+C<lines> and C<get> for reading. All four are available as subroutines
+(defaulting to the C<$*OUT> and C<$*ARGFILES> file handles) and as
+methods on file handles.
+
+File handles are of type C<IO::Handle>, and can be created with C<&open>.
+Paths are generally passed as strings or C<IO::Path> objects.
+
+C<&dir> returns C<IO::File> and C<IO::Dir> objects, which are
+subclasses of C<IO::Path>.
-[Note: if a method declaration indicates a method name qualified by
-type, it should be taken as shorthand to say which role or class the
-method is actually declared in.]
+
+ default handle
+ routine for sub form purpose
+ ======= =========== =======
+ print $*OUT string-based writng
+ say $*OUT string-based witing
+ get $*ARGFILES read a line (Str)
+ lines $*ARGFILES read all lines (Str)
+ read binary reading (Buf)
+ write binary writing (Buf)
+
+File tests are performed through C<IO::Path> objects.
+
+=head1 Functions
=over 4
@@ -50,10 +72,10 @@ X<open>
Any :$nl = "\n",
Bool :$chomp = True,
...
- --> IO
+ --> IO::Handle
) is export
-A convenience method/function that hides most of the OO complexity.
+A convenience function that hides most of the OO complexity.
It will only open normal files. Text is the default. Note that
the "Unicode" encoding implies figuring out which actual UTF is
in use, either from a BOM or other heuristics. If heuristics are
@@ -74,259 +96,229 @@ and the parent directory are excluded, which can be controlled with the
C<$test> named parameter. Only items that smart-match against this test are
returned.
-=item getc
-X<getc>
-
- method getc (Int $chars = 1 --> Char)
-
-See below for details.
-
-=item print
-X<print>
-
- method print (*@LIST --> Bool)
- multi print (*@LIST --> Bool)
- method Str::print (IO $io --> Bool)
- method Array::print (IO $io --> Bool)
- method Hash::print (IO $io --> Bool)
+The return value is a list of C<IO::File> and C<IO::Dir> objects.
-See below for details.
+=item note
-=item say
-X<say>
+ multi multi note (*@LIST --> Bool)
- method say (*@LIST --> Bool)
- multi say (*@LIST --> Bool)
- method Str::say (IO $io --> Bool)
- method Array::say (IO $io --> Bool)
- method Hash::say (IO $io --> Bool)
+Does a "say" to C<$*ERR>, more or less. Like C<warn>, it adds a
+newline only if the message does not already end in newline. Unlike
+C<warn>, it is not trappable as a resumable exception because it
+outputs directly to C<$*ERR>. You can suppress notes in a lexical
+scope by declaring:
-See below for details.
+ only note(*@) {}
-=item note
-X<note>
+=item slurp
- multi note (*@LIST --> Bool)
+ multi slurp (IO $fh = $*ARGFILES,
+ Bool :$bin = False,
+ Str :$enc = "Unicode",
+ --> Str|Buf
+ )
+ multi slurp (Str $filename,
+ Bool :$bin = False,
+ Str :$enc = "Unicode",
+ --> Str|Buf
+ )
-See below for details.
+Slurps the entire file into a C<Str> (or C<Buf> if C<:bin>) regardless of context.
+(See also C<lines>.)
-=item printf
-X<printf>
+The routine will C<fail> if the file does not exist, or is a directory.
- method printf (Str $fmt, *@LIST --> Bool)
- multi printf (Str $fmt, *@LIST --> Bool)
+=item spurt
-See below for details.
+ multi spurt (IO $fh,
+ Str $contents,
+ Str :$enc = $?ENC,
+ Bool :append = False,
+ Bool :$createonly = False,
+ )
+ multi spurt (IO $fh,
+ Buf $contents,
+ Bool :append = False,
+ Bool :$createonly = False,
+ )
+ multi spurt (Str $filename,
+ Str $contents,
+ Str :$enc = $?ENC,
+ Bool :append = False,
+ Bool :$createonly = False,
+ )
+ multi spurt (Str $filename,
+ Buf $contents,
+ Bool :append = False,
+ Bool :$createonly = False,
+ )
-=item uri
-X<uri>X<ftp>X<http>
+Opens the file for writing, dumps the contents, and closes the file.
- method uri(Str $uri --> IO::Streamable);
- sub uri(Str $uri --> IO::Streamable);
+This routine will C<fail> if the file exists, unless the C<:append> flag is
+set, in which case it will instead add the given contents at the end of the
+file.
-Returns an appropriate C<IO::Streamable> descendant, with the type depending on the uri
-passed in. Here are some example mappings:
+The routine will also C<fail> with the corresponding exception if there was any
+other error in opening, writing, or closing.
- URI type IO type
- ======== =======
- file: IO::File or IO::Directory
- ftp: IO::Socket::INET (data channel)
- http: IO::Socket::INET
+If the C<:createonly> flag was passed, C<slurp> fails if the file already
+exists, and refuses to overwrite it.
-These can naturally be overridden or added to by other modules.
+=item chdir
-=item %*PROTOCOLS dynamic variable
+ multi sub chdir(Str:D)
+ multi sub chdir(IO::Path::D)
-For each protocol, stores a type name that should be instantiated by calling the C<uri>
-constructor on that type, and passing in the appropriate uri.
+Changes the current working directory to the new value. Fails on error.
=back
-=head1 Roles
-
-The functionality of C<IO> objects is broken down into several roles,
-which should identify the features each object supports.
+=head1 IO Types
=head2 IO
+ role IO { };
+
The base role only tags that this is an C<IO> object for more generic
purposes. It doesn't specify any methods or attributes.
-=head2 IO::Readable
-This role provides unbuffered read access to the data stream.
+=head2 IO::Handle
- role IO::Readable {
- has $.isReadable;
- method read(Int $bytes --> Buf)
- }
+ class IO::Handle does IO { ... }
-When the C<$.isReadable> is set, it tries to change the readability of the filehandle. This
-is not always possible, but can be done in a number of cases. C<IO::Socket> can remove
-readability by calling C<shutdown>, for example.
+A handle of a file, pipe or anything else that supports reading or
+writing like a file.
-=over
-
-=item method read(Int $bytes --> Buf)
-
-Tries to read C<$bytes> bytes and return it as a C<Buf>. The C<Buf> may be
-shorter than the actual specified number of C<$bytes>.
-
-This is "raw" read. You're going to
-have plain octets stored in C<$buf>. If what you want is a C<Str>,
-you're going to need to C<.decode> it after C<read>ing, or use "getc" or other
-C<IO::Readable::Encoded> methods.
-
-=back
-
-=head2 IO::Writeable
-
-This role provides unbuffered write access to the data stream.
-
- role IO::Writeable {
- has $.isWriteable;
- method write(Buf $buf --> Int)
- }
-
-When the C<$.isWriteable> is set, it tries to change the writeability of the filehandle.
-This is not always possible, but can be done in a number of cases. C<IO::Socket> can remove
-writeability by calling shutdown(), for example.
-
-=over
+=over 4
-=item method write(Buf $buf --> Int)
+=item get
-Tries to write C<$buf>. The actual number of bytes
-written is returned. It might return unthrown failures, to be
-specified by each C<IO> implementation.
+ method get() returns Str:D
-This is "raw" write. C<$buf> contains plain octets. If you want to C<write>
-a C<Str>, you should C<.encode> it first, or use "print" or other
-C<IO::Writeable::Encoded> methods.
+Reads and returns one line from the handle. Uses C<input-line-separator>
+to determine where a line ends.
-=back
+=item lines
-=head2 IO::Seekable
+ method lines($limit = Inf)
-=over
+Returns a lazy list of lines read via the C<get> method, limited to C<$limit>
+lines.
-=item method eoi( --> Bool)
+=item getc
+X<getc>
-EOI = End Of Input -- equivalent to End Of File, but applies to other kinds of sockets as
-well.
+ method getc (IO::Handle:D: Int $chars = 1 --> Str)
-Returns true if it's the end of the input (i.e. end of file or whatever), returns false if
-not, fails if we can't say for certain.
+Reads C<$chars> and returns them
-=item method seek(Int $position --> Bool)
+=item print
+X<print>
-Position this stream into C<$position>. The meaning of this position is
-always in "octets".
+ method print (IO::Handle:D: *@LIST --> Bool)
+ multi print (*@LIST --> Bool)
-=item method tell( --> Int)
+Stringifies each element, concatenates those strings, and sends the
+result to the output.
+Returns C<Bool::True> if successful, C<Failure> otherwise.
-Returns the current raw position in the stream in number of "octets".
+The compiler will warn you if use a bare sub C<print> without arguments.
+(However, it's fine if you have an explicit argument list that evaluates to
+the empty list at runtime.)
-=back
+ print; # warns
+ if $_ { print } # warns
+ if $_ { print() } # ok, but does nothing
+ if $_ { print () } # ok, but does nothing
-=head2 IO::Buffered
+=item say
+X<say>
-Indicates that this object performs buffering. The management of the
-buffer is completely implementation specific.
+ method say (IO::Handle:D: *@LIST --> Bool)
+ multi say (*@LIST --> Bool)
-=over
+This is identical to print() except that it stringifies its arguments by calling
+C<.gist> on them and auto-appends a newline after the final argument.
-=item method flush( --> Bool)
+ Was: print "Hello, world!\n";
+ Now: say "Hello, world!";
-Flushes the buffers associated with this object.
+As with C<print>, the compiler will warn you if you use a bare sub C<say>
+without arguments.
-=item method autoflush( --> Bool) is rw
+=item printf
+X<printf>
-Forces this object to keep its buffers empty
+ method printf (Str $fmt, *@LIST --> Bool)
+ multi printf (IO::Handle:D: Str $fmt, *@LIST --> Bool)
-If set to nonzero, forces a flush right away and after every write
-or print on the currently selected output channel.
-Default is 0 (regardless of whether the channel is really buffered
-by the system or not;
-C<$OUT_FH.autoflush> tells you only whether you've asked Perl
-explicitly to flush after each write).
-C<$*OUT> will typically be line buffered if output is to the
-terminal and block buffered otherwise.
-Setting this variable is useful primarily when you are
-outputting to a pipe or socket,
-such as when you are running a Perl program under rsh
-and want to see the output as it's happening.
-This has no effect on input buffering.
+Output through C<Str.sprintf>. See L<S32::Str> for details.
+=item write
-=back
+ method write(IO::Handle:D: Buf $buf --> Int)
-=head2 IO::Streamable
+Tries to write C<$buf>. The actual number of bytes
+written is returned. It might return unthrown failures, to be
+specified by each C<IO> implementation.
-This role represents objects that depend on some external resource,
-which means that data might not be available at request.
+This is "raw" write. C<$buf> contains plain octets. If you want to C<write>
+a C<Str>, you should C<.encode> it first, or use "print" or other
+C<IO::Writeable::Encoded> methods.
- role IO::Streamable does IO {...}
+=item slurp
-=over
+ method slurp()
-=item new()
+Reads all the remaining contents of the handle into a C<Str> (or a C<Buf>
+if the handle was opened with C<:bin>).
- method new(
- Bool :$NoOpen,
- Bool :$Blocking,
- --> IO::Streamable
- ) {...}
+=item t
-Unless the NoOpen option is passed, an open will be done on the C<IO> object when it is
-created.
+ method t() returns Bool:D
-If blocking is passed in, .blocking() is called (see below).
+Returns C<True> if the handle is opened to a tty.
-=item method blocking( --> Bool) is rw
+=item p
-This allows the user to control whether this object should do a
-blocking wait or immediately return in the case of not having data
-available.
+ method p() returns Bool:D
-=item uri
+Returns C<True> if the handle is opened to a pipe.
- method uri(Str $uri --> IO::Streamable) {...}
+=item eof
-This should be callable on the class, and act like a kind of "new()" function. When given
-a URI, it returns an C<IO::Streamable> of the appropriate type, and throws an error when an
-inappropriate type is passed in. For example, calling C<IO::File.uri('http://....')> will
-throw an error (but will suggest using just uri('http://...') instead).
+ method eof() returns Bool:D
-=back
+Returns C<True> if the handle is exhausted.
-=head2 IO::Encoded
+=item seek
-This is a generic role for encoded data streams.
+method seek(Int $position, Int $whence --> Bool)
-=over
+Position this stream into C<$position>. The meaning of this position is
+always in "octets".
-=item method encoding( --> Str) is rw
+Fails if the handle is not seekable.
-=item method locale( --> Str) is rw
+TODO: make $whence an Enum
-Encoding and locale are required for sane conversions.
+=item tell
-=back
+ method tell() returns Int:D:
-=head2 IO::Readable::Encoded
+Returns the current raw position in the stream in number of "octets".
-This role provides encoded access to a readable data stream, implies
-C<IO::Encoded>. Might imply C<IO::Buffered>, but that's not a requirement.
+=item ins
-=over
+ method ins( --> Int)
-=item method ins( --> Int)
+Returns the number of lines that have been read with C<get>.
-Returns the number of lines or records that have been input.
-Now with cleaned-up localization usage.
+=item input-line-separator
-=item method input-line-separator( --> Str) is rw
+ method input-line-separator( --> Str) is rw
This regulates how "get" and "lines" behave.
@@ -348,748 +340,229 @@ You may also set it to a regular expression. The value of C<$/>
will be (temporarily) set to the matched separator upon input,
if you care about the contents of the separator.
-=item method input-field-separator( --> Str) is rw
-
-[Deprecated.]
-
-=item method input-escape( --> Str) is rw
-
-[Deprecated.]
-
-=item method get( --> Str)
-
-Reads the stream before it finds a C<$.input-line-separator> and
-returns it (autochomped by default).
-
-=item method readfield( --> Str)
-
-[Deprecated. Use split or comb or an ILS regex.]
-
-=item method getc( --> Char)
-
-Reads the next character in the set C<$.encoding>,
-or C<Failure> at end of file, or if there was
-an error (in either case C<$!> is set). Note that this
-function cannot be used interactively as a C<readkey()> function, since under
-Unicode you can't tell the end of a grapheme until you
-see the beginning of the next one.
-
-[TODO someone needs to define something like C<readkey()> for terminal IO.
-Though most event-based programs will just want to feed keystrokes into the
-event queue.]
-
-=item multi method comb ( Regex $matcher, Int $limit = * )
-
-Reads everything into a string, and calls C<.comb> on it with the same
-parameters. See C<Str::comb>.
-
-=back
-
-=head2 IO::Writeable::Encoded
-
-This role provides encoded access to a writeable data stream, implies
-C<IO::Encoded>. Might imply C<IO::Buffered>, but that's not a requirement.
-
-If these are called in their non-object form, they operate on C<$*OUT>, except in the
-case of warn(), which operates on C<$*ERR>. The form with leading dot prints C<$_> to
-the appropriate handle unless C<$_> happens to be a filehandle.
-
-=over
-
-=item Int method outs()
-
-Returns the number of lines or records that have been output so far.
-
-=item method output-line-separator( --> Str) is rw
-
-This regulates how say behaves.
-
-=item method output-field-separator( --> Str) is rw
-
-[Deprecated.]
-
-=item method output-escape( --> Str) is rw
-
-[Deprecated.]
-
-=item method Str::print (IO $io = $*OUT --> Bool)
-
-=item method Str::say (IO $io = $*OUT --> Bool)
-
-=item method Array::print(IO $io = $*OUT --> Bool)
-
-=item method Array::say(IO $io = $*OUT --> Bool)
-
-=item method Hash::print(IO $io = $*OUT --> Bool)
-
-=item method Hash::say(IO $io = $*OUT --> Bool)
-
-Stringifies the invocant (if necessary) and then sends it to the output.
-C<say> should add an additional C<$.output-line-separator>.
-
-
-=item method print (*@LIST --> Bool)
-
-=item multi print (*@LIST --> Bool)
-
-
-Stringifies each element, concatenates those strings, and sends the
-result to the output.
-Returns C<Bool::True> if successful, C<Failure> otherwise.
-
-The compiler will warn you if use a bare C<print> without arguments.
-(However, it's fine if you have an explicit argument list that evaluates to
-the empty list at runtime.)
-
- print; # warns
- if $_ { print } # warns
- if $_ { print() } # ok, but does nothing
- if $_ { print () } # ok, but does nothing
-
-=item method say (*@LIST --> Bool)
-
-=item multi say (*@LIST --> Bool)
-
-This is identical to print() except that it stringifies its arguments by calling
-C<.gist> on them and auto-appends the C<output-line-separator> after the final
-argument.
-
- Was: print "Hello, world!\n";
- Now: say "Hello, world!";
-
-As with C<print>, the compiler will warn you if you use a bare C<say> without
-arguments.
-
-=item multi note (*@LIST --> Bool)
-
-Does a "say" to C<$*ERR>, more or less. Like C<warn>, it adds a
-newline only if the message does not already end in newline. Unlike
-C<warn>, it is not trappable as a resumable exception because it
-outputs directly to C<$*ERR>. You can suppress notes in a lexical
-scope by declaring:
-
- only note(*@) {}
-
-=item method printf ($self: Str $fmt, *@LIST --> Bool)
-
-=item multi printf (Str $fmt, *@LIST --> Bool)
-
-The function form works as in Perl 5 and always prints to C<$*OUT>.
-
-=back
-
-For any handle marked as textual, all these output calls intercept any newline
-character and translate it to the current C<output-line-separator> if it
-is defined as something other than newline. No such translation is done on
-binary handles, though you may still specify a record separator. In any case,
-escaping separators is the responsibility of the programmer.
-
-=head2 IO::Closeable
-
-This role indicates that this object can be closed.
-
-=over
-
-=item method close( --> Bool)
-
-Closes the file or pipe associated with the object.
-
-Returns C<True> on success, but might return an unthrown C<Failure>.
-Returns true only if C<IO> buffers are successfully flushed and closes the system
-file descriptor.
-
-Unlike in Perl 5, an C<IO> object is not a special symbol table entry
-neither this object is available magically anywhere else. But as in
-Perl 5, unless stated otherwise, C<IO::Closeable> objects always close
-themselves during destruction.
-
-=back
-
-=head2 IO::Socket
-
- role IO::Socket
- does IO::Closeable
- does IO::Readable
- does IO::Writeable
- does IO::Streamable
- {
- has %.options;
- has Bool $.Listener;
- ...
- }
-
-Accessing the C<%.options> would on Unix be done with I<getsockopt(2)>/I<setsockopt(2)>.
-
-The $.Listener attribute indicates whether the socket will be a listening socket when
-opened, rather than indicating whether it is currently listening.
-
-=over
-
-=item new
-
- method new(
- :$Listener, # initialises $.Listener
- )
-
-The initial value of the $.Listener attribute is defined according to the following rules:
-
- * If $Listener is passed to .new(), then that value is used
- * If neither a local address nor a remote address are passed in, throw an exception
- * If no remote address is passed, then $.Listener is set to SOMAXCONN
- * If no local address is used, then $Listener is set to 0
- * If both local and remote addresses are used, throw an exception that asks people to
- specify $Listener
-
-=item open
-
- method open()
-
-If $.Listener is true, does a I<bind(2)> and a I<listen(2)>, otherwise does a
-I<connect(2)>.
-
-It's end-user use case is intended for the case where NoOpen is passed to .new(). .new()
-itself will presumably also call it.
-
=item close
- method close()
-
-Implements the close() function from IO::Closeable by doing a shutdown on the connection
-(see below) with @how set to ('Readable', 'Writeable').
-
-=item shutdown
-
- method shutdown(Str @how)
-
-Does a I<shutdown(2)> on the connection. See also IO::Readable.isReadable and
-IO::Writeable.isWriteable.
-
-$how can contain 1 or more of the strings 'Readable' and 'Writeable'.
-
-=item accept
-
- method accept( --> IO::Socket)
-
-=item method read(Int $bytes --> Buf)
-
-Implements the IO::Readable interface by doing a I<recv(2)>.
-
-=item method write(Buf $buf --> Int)
-
-Implements the IO::Writeable interface by doing a I<send(2)>.
-
-=item getpeername
+Closes the handle. Fails on error.
=back
-=head2 IO::FileDescriptor
+=head1 IO::FileTests
-This role indicates that this object actually represents an open file
-descriptor in the os level.
+ role IO::FileTests does IO { ... }
-=over
+Provides ways to inspect a file or path without opening it.
-=item method int fileno()
+If you apply that role to a class, that class must provide a C<path>
+method which C<IO::FileTests>' method will call to obtain the path to
+test. This C<path> method must return a C<Str:D>.
-File descriptors are always native integers, conforming to C89.
+The methods are typically only one letter long (for now; perl 5 tradition
+strikes) and are summarized in the following table:
-=back
+ M Test performed
+ = ==============
+ r $.path is readable by effective uid/gid.
+ w $.path is writable by effective uid/gid.
+ x $.path is executable by effective uid/gid.
+ o $.path is owned by effective uid.
-=head1 Classes
+ R $.path is readable by real uid/gid.
+ W $.path is writable by real uid/gid.
+ X $.path is executable by real uid/gid.
+ O $.path is owned by real uid.
-=head2 IO::File
-
-This does file input and output.
-
- class IO::File does IO::Streamable {
- ...
- }
-
-=over
-
-=item new
-
- method new(
- Path :$Path,
- :$fd
- Bool :$NoOpen,
- :$Writeable,
- :$Readable
- );
-
-The C<Path> and C<fd> options are mutually exclusive.
-
-C<NoOpen> is passed to C<IO::Streamable.new()>
+ e $.path exists.
+ s $.path has a size > 0 bytes
-Examples:
+ f $.path is a plain file.
+ d $.path is a directory.
+ l $.path is a symbolic link.
+ p $.path is a named pipe (FIFO)
+ S $.path is a socket.
+ b $.path is a block special file.
+ c $.path is a character special file.
- # Read, no interpolation
- $fobj = IO::File.new(Path => qp{/path/to/file});
+ u $.path has setuid bit set.
+ g $.path has setgid bit set.
+ k $.path has sticky bit set.
- # Write, interpolation
- $fobj = IO::File.new(
- Path => p:qq{$filename},
- Writeable => 1
- );
+TODO: methods created, accessed, modified
- # Read using file descriptor
- $fobj = IO::File.new(fd => $fd);
+=head2 IO::Path
-This final example associates an C<IO> object with an already-open file descriptor,
-presumably passed in from the parent process.
+ class IO::Path is Cool does IO::FileTest { }
-=item open()
+Holds a path of a file or directory. The path is generally divided
+into three parts, the I<file system>, I<directory> and I<base name>.
-This function opens a file that had the C<NoOpen> option passed to the C<new> method.
+On Windows, the file system is a drive letter like C<C:>. Relative paths
+never have a file system part. On UNIX-based systems, the file system part
+is empty.
-=item IO.truncate
+The base name is name of the file or directory that the IO::Path object
+represents, and the directory is the part of the path leading up to the base
+name.
-=item IO.fcntl
-
-Available only as a handle method.
-
-=back
-
-=head2 IO::Directory
-
- role IO::Directory does IO::Streamable {
- ...
- }
-
-=over
-
-=item open
-
- $dir.open(
- Str :$enc = "Unicode",
- );
-
-Opens a directory for processing, if the C<new> method was passed the C<NoOpen> option.
-Makes the directory looks like
-a list of autochomped lines, so just use ordinary C<IO> operators after the open.
-
-=back
-
-=head2 IO::FileSystems
-
-This represents the file systems mounted on the current machine (i.e. accessible via a
-filesystem path).
-
- class IO::FileSystems {
- has Str $.illegal-chars; # i.e. /\x0
- has Int $.max-path;
- has Int $.max-path-element;
- ...
- }
-
-=over 4
-
-=item chdir FILENAME
-X<chdir> X<cd>
-
-=item chdir
-
-Changes the current working directory to the one specified by FILENAME.
-If it succeeds it returns true, otherwise it returns C<Failure> and
-sets C<$!> (errno). Note, though, that chdir affects only the system
-directory; most things in Perl 6 that need a current directory depend
-on their thread's copy of $*CWD, so you probably want to set $*CWD
-instead of using chdir().
-
-
-=item glob
-
-Returns C<Path> objects. Path.Encoding is set to $?ENC unless the
-Encoding parameter is passed in (see Path for further discussion of
-encoding).
-
-=item rename
-
-=back
-
-=head2 Path
-
-The "Path" role covers both the path to the file, and the file metadata. They
-are usually created with the qp{/path/to/file} syntax. It could be a directory,
-file, link, or something else OS-specific.
-
- role Path does Str does Array {
- has Str $.Type;
- has Str @.Elements;
- has Str $.Encoding;
- has Buf $.Binary;
- has IO::ACL @.ACLs;
- has %.times;
- ...
- }
-
-C<$.Type> can be C<File>, C<Directory>, C<Link>, or C<Other>. See
-C<.create()> method documentation for how it is set.
-
-The C<@.Elements> array is a list of Str that contain the path elements, but
-all are checked before being pushed onto the array. Note that @.Elements
-can not be accessed unless $.Encoding is defined.
-
-The C<%.times> has keys that can be e.g. C<ctime>, C<Modification>, and
-C<Access> (and maybe others on other operating systems), and the values are
-all C<Instant> objects.
-
-When a Path is used as a Str, it allows some operations, so that it can
-be concatenated easily with other strings. When used as an Array, it
-acts as an array of path elements.
-
-=head3 Methods
+ path file system directory base name
+ /usr/bin/gvim /usr/bin gvim
+ /usr/bin/ /usr bin
+ C:\temp\f.txt C: temp f.txt
=over 4
-=item new
-
-While new Path objects will normally be created with the qp{/path/to/file}
-syntax, there are also OO-related alternatives.
-
-This is called automatically on object creation.
-
- multi method new(
- Stringy :$Path,
- Str :@PathElements,
- Str :$Encoding,
-
- Str :@Constraints,
- Str :$Protocol,
-
- Str :$Target,
- Str :$LinkType,
- Str :$Type,
- );
-
-Path and PathElements are mutually exclusive.
-
-If the $Encoding parameter is not defined, then, if Path is a Buf,
-the $.Encoding attribute remains undefined, otherwise it is set to
-$?ENC. There are
-a number of features that don't work without the encoding being set.
-
-$Constraints determines whether the $Path and $Target strings should be
-assumed to be Unix-style, Windows-style, or something else.
-
-If the Type option is not passed in, the Path.Type attribute is initialised
-as follows:
-
- Value Condition
- ===== =========
- Directory $Path ends in a separator (i.e. /)
- Link $Target is specified
- Other $Protocol is specified
- Undefined All other cases
-
-If the $.Type attribute is read (which will happen in a number of cases,
-including when you read $.Target and $.LinkType), but is still undefined,
-then an attempt is
-made to determine what its type should be from the filesystem. If no
-answers are found using this method, then it defaults to "File".
-
-The C<Target> and C<LinkType> options are only relevant for links that have
-not been created yet, or are to be overwritten; in all other cases,
-they will be determined from the filesystem. If Target is not specified,
-this Path is assumed not to be a link. If LinkType is not specified,
-then the default is used (symbolic, on a Unix system).
-
-Examples:
-
- # These three do the same thing (on a Unix machine)
- $path = qp{/home/wayland};
- $path = Path.new(PathElements => ['home', 'wayland']);
- $path = Path.new(Constraints => ['Unix'], Path => qp{/home/wayland});
- $path = Path.new(Path => qp{/home/wayland});
-
- # This creates a symlink from /home/wayland/m to /home/wayland/Music
- $path = Path.new(
- Path => qp{/home/wayland/m},
- Target => qp{/home/wayland/Music},
- );
-
=item path
-method path( --> Str);
-
-Returns @.elements concatenated together for use as a string. Usually this
-is the path that it was originally created with.
-
-=item canonpath
+Returns the path (file system, directory and base name joined together) as
+a string.
- method canonpath( --> Str);
+=item filesystem
-No physical check on the filesystem, but a logical cleanup of a path.
+Returns the file system part of the path
-=item realpath
+=item directory
- method realpath( --> Str);
+Returns the directory part of the path
-Gets the real path to the object, resolving softlinks/shortcuts, etc
+=item basename
-=item resolvepath
+Returns the base name part of the path
- method resolvepath(Str :@Types --> Str);
+=item Str
-@Types can contain "real" and "canon", in any order, and the
-method will run realpath and canonpath in the order specified.
+Stringifies to the base name.
-=item ACCEPTS
-
- multi method ACCEPTS(Path $filename);
-
-Test whether the specified filename is the same file as this file. On a
-Unix system, this would presumably be done by comparing inode numbers or
-something.
-
-=item create
-X<mkdir> X<md> X<directory, create> X<touch>
+=back
- method create(
- Bool :$Recursive,
- Bool :$Truncate,
- )
+=head2 IO::File
-Creates/touches the specified path. In the case of a link or a directory, no
-parameters are required. If a file doesn't exist, then no parameters are
-required. If the path already exists, then an exception is thrown, unless
-the file is an ordinary file or a link, and $Truncate is true.
+ class IO::File is IO::Path { ... }
-The $Recursive option specifies that any necessary parent directories should
-also be created.
+Represents a path that is known to be a plain file (not a directory), at
+least at the time when the object was created.
-=item touch
+=head2 IO::Dir
-Update timestamps on a file.
+ class IO::Dir is IO::Path { ... }
-=item delete
+Represents a path that is known to be a directory, at
+least at the time when the object was created.
-X<rmdir> X<rd> X<directory, remove>
+=head1 Here Be Dragons
- method delete(Bool :$Recursive --> Int);
+Everything below this point hasn't been reviewed properly
-This deletes the C<Path> from the filesystem. If the node has children, it
-throws an error unless the C<Recursive> option is specified. It returns the
-number of nodes deleted, and may throw an exception.
+=head2 IO::Socket
-=item get
+ role IO::Socket {
+ has %.options;
+ has Bool $.Listener;
+ ...
+ }
- multi get ()
+Accessing the C<%.options> would on Unix be done with I<getsockopt(2)>/I<setsockopt(2)>.
-Returns the next line from $*ARGFILES. (Note that other C<get> functions
-and methods are operations on any iterator, not just an IO handle.)
+The $.Listener attribute indicates whether the socket will be a listening socket when
+opened, rather than indicating whether it is currently listening.
-=item lines
+=over
- method lines ($handle:
- Any $limit = *,
- Bool :$bin = False,
- Str :$enc = "Unicode",
- Any :$nl = "\n",
- Bool :$chomp = True,
- --> List
- )
+=item new
- multi lines (IO $fh = $*ARGFILES,
- Any $limit = *,
- Bool :$bin = False,
- Str :$enc = "Unicode",
- Any :$nl = "\n",
- Bool :$chomp = True,
- --> List
+ method new(
+ :$Listener, # initialises $.Listener
)
- # See also Str.lines and lines(Str)
+The initial value of the $.Listener attribute is defined according to the following rules:
-Returns some or all the lines of a file or entries in a directory
-as a C<List> regardless of context.
-See also C<slurp>. Note that lists are lazy by default, but you
-can always ask for C<eager lines>. Note that the limit semantics cannot be
-duplicated by subscripting, since
+ * If $Listener is passed to .new(), then that value is used
+ * If neither a local address nor a remote address are passed in, throw an exception
+ * If no remote address is passed, then $.Listener is set to SOMAXCONN
+ * If no local address is used, then $Listener is set to 0
+ * If both local and remote addresses are used, throw an exception that asks people to
+ specify $Listener
- $fh.lines[^5]
+=item open
-reads all the lines before the subscript gives you the first five,
-whereas
+ method open()
- $fh.lines(5)
+If $.Listener is true, does a I<bind(2)> and a I<listen(2)>, otherwise does a
+I<connect(2)>.
-reads only five lines from the handle. Note that
+It's end-user use case is intended for the case where NoOpen is passed to .new(). .new()
+itself will presumably also call it.
- $fh.lines(1)
+=item close
-is equivalent to
+ method close()
- $fh.get
+Implements the close() function from IO::Closeable by doing a shutdown on the connection
+(see below) with @how set to ('Readable', 'Writeable').
-If fewer lines are available than the limit, it is not an error;
-you just get the number of lines available.
+=item shutdown
-=item slurp
+ method shutdown(Str @how)
- method slurp ($handle:
- Bool :$bin = False,
- Str :$enc = "Unicode",
- --> Str|Buf
- )
- multi slurp (IO $fh = $*ARGFILES,
- Bool :$bin = False,
- Str :$enc = "Unicode",
- --> Str|Buf
- )
- multi slurp (Str $filename,
- Bool :$bin = False,
- Str :$enc = "Unicode",
- --> Str|Buf
- )
+Does a I<shutdown(2)> on the connection. See also IO::Readable.isReadable and
+IO::Writeable.isWriteable.
-Slurps the entire file into a C<Str> (or C<Buf> if C<:bin>) regardless of context.
-(See also C<lines>.)
+$how can contain 1 or more of the strings 'Readable' and 'Writeable'.
-The routine will C<fail> if the file does not exist, or is a directory.
+=item accept
-=item spurt
+ method accept( --> IO::Socket)
- multi method spurt ($handle:
- Str $contents,
- Str :$enc = $?ENC,
- Bool :append = False,
- Bool :createonly = False,
- )
- multi method spurt ($handle:
- Buf $contents,
- Bool :append = False,
- Bool :createonly = False,
- )
- multi spurt (IO $fh,
- Str $contents,
- Str :$enc = $?ENC,
- Bool :append = False,
- Bool :createonly = False,
- )
- multi spurt (IO $fh,
- Buf $contents,
- Bool :append = False,
- Bool :createonly = False,
- )
- multi spurt (Str $filename,
- Str $contents,
- Str :$enc = $?ENC,
- Bool :append = False,
- Bool :createonly = False,
- )
- multi spurt (Str $filename,
- Buf $contents,
- Bool :append = False,
- Bool :createonly = False,
- )
+=item method read(Int $bytes --> Buf)
-Opens the file for writing, dumps the contents, and closes the file.
+Reads and returns C<$bytes> bytes from the handle
-If the C<:createonly> flag is set and the file already exists before
-opening, this routine will C<fail>. With an unset C<:createonly> flag,
-the file will instead be silently overwritten, unless the C<:append>
-flag is set, in which case the routine will instead add the given
-contents at the end of the file.
+=item method write(Buf $buf --> Int)
-The routine will also C<fail> with the corresponding exception
-if there was any other error in opening, writing, or closing.
+Implements the IO::Writeable interface by doing a I<send(2)>.
=back
-=head3 Other things
-
-=over 4
+=head2 IO::Socket::INET
-=item IO ~~ :X
-X<:r>X<:w>X<:x>X<:o>X<:R>X<:W>X<:X>X<:O>X<:e>X<:z>X<:f>X<:d>X<:l>X<:p>
-X<:S>X<:b>X<:c>X<:t>X<:u>X<:g>X<:k>X<:T>X<:B>X<:M>X<:A>X<:C>
-
-=item EXPR ~~ :X
-
- $file.:X
- $file ~~ :X
-
-A file test, where X is one of the letters listed below. This unary
-operator takes one argument, either a filename or a filehandle, and
-tests the associated file to see if something is true about it.
-
-A C<Pair> used as a pattern is treated as a file test.
-
- :r File is readable by effective uid/gid.
- :w File is writable by effective uid/gid.
- :x File is executable by effective uid/gid.
- :o File is owned by effective uid.
-
- :R File is readable by real uid/gid.
- :W File is writable by real uid/gid.
- :X File is executable by real uid/gid.
- :O File is owned by real uid.
-
- :e File exists.
- :s File has a size > 0 bytes
-
- :f File is a plain file.
- :d File is a directory.
- :l File is a symbolic link.
- :p File is a named pipe (FIFO), or Filehandle is a pipe.
- :S File is a socket.
- :b File is a block special file.
- :c File is a character special file.
- :t Filehandle is opened to a tty.
-
- :u File has setuid bit set.
- :g File has setgid bit set.
- :k File has sticky bit set.
-
-Each of these is redirected (by C<Pair.ACCEPTS>) to the
-corresponding method name on an IO object. (These methods are not
-defined on bare strings). Each test returns a boolean, and may be
-negated with a C<!> after the colon. They maybe ANDed and ORed using
-junctional logic. In fact, this is the primary reason for writing
-them as a pattern match; if you only want one test, you could just call
-the individual IO method directly and more efficiently. In any case,
-you must call the C<.s> method to return the file's size in bytes.
-
-There is no <.z> method, so just write C<:!s> to test a file for zero size.
-Likewise, just call C<.s> directly if you actually want to know the file's
-size, since C<~~ :s> only returns a boolean.
-
-The C<.T> and C<.B> methods will be replaced by some filetype guessing
-methods more appropriate to the age of Unicode. There are likely methods
-to return the various ages of the file corresponding to Perl 5's C<-M>,
-C<-A>, and C<-C> times, but they make no sense as booleans, so also call
-those methods directly (whatever they end up being named).
-
-The interpretation of the file permission operators C<:r>, C<:R>,
-C<:w>, C<:W>, C<:x>, and C<:X> is by default based on:
+ class IO::Socket::INET does IO::Socket {
+ has Str $.proto = 'TCP';
+ has Str $.host;
+ has Int $.port;
+ has Str $.localhost;
+ has Int $.localport;
+ ...
+ }
=over
-=item * The mode of the file and the uids and gids of the user
+=item new
-=item * ACLs (access control lists)
+ multi method new(:$host!, :$port, *%attributes) { ... }
+ multi method new(:$localhost!, :$localport, :$listen! *%attributes) { ... }
-=item * read-only filesystems
+Creates a new socket and opens it.
=back
-There may be other reasons you can't actually read, write, or execute
-the file. Such reasons may be for example network filesystem access
-controls and unrecognized executable formats.
+=head2 IO::Handle
+
+This role indicates that this object actually represents an open file
+descriptor in the os level.
-Also note that, for the superuser on the local filesystems, the C<:r>,
-C<:R>, C<:w>, and C<:W> tests always return 1, and C<:x> and C<:X> return 1
-if any execute bit is set in the mode. Scripts run by the superuser
-may thus need to do a C<stat> to determine the actual mode of the file,
-or temporarily set their effective uid to something else.
+=over
-You can test multiple features using junctions:
+=item method int fileno()
- if $filename.IO ~~ :r & :w & :x {...}
+File descriptors are always native integers, conforming to C89.
=back
+
+=head1 Conjectural Stuff
+
+Everything below this point should be considered as mere ideas for
+future evolution, not as things that a compiler write should implement
+unquestioningly.
+
=head2 IO::ACL
This is a basic abstraction; for better control, use the operating-system specific
@@ -1134,27 +607,6 @@ done with groups too. Works on Unix, at least.
The C<$.owningObject> attribute of C<ACL> shows what the ACL is set on. On a
Windows system, this can be a parent directory, as permissions are inherited.
-=head2 IO::Socket::INET
-
- class IO::Socket::INET does IO::Socket {
- has Str $.proto = 'TCP';
- has Str $.host;
- has Int $.port;
- has Str $.localhost;
- has Int $.localport;
- ...
- }
-
-=over
-
-=item new
-
- multi method new(:$host!, :$port, *%attributes) { ... }
- multi method new(:$localhost!, :$localport, :$listen! *%attributes) { ... }
-
-Creates a new socket and opens it.
-
-=back
=head2 IO::Pipe
@@ -1206,11 +658,11 @@ reader and writer ends of the pipe.
=back
-=head1 OS-specific classes
+=head2 OS-specific classes
-=head2 Unix
+=head3 Unix
-=head2 Path::Unix
+=head3 Path::Unix
=over
@@ -1281,7 +733,7 @@ to false.
=back
-=head2 IO::Socket::Unix
+=head3 IO::Socket::Unix
role IO::Socket::Unix does IO::Socket {
has Str $.RemoteAddr, # Remote Address
@@ -1318,7 +770,7 @@ reader and writer ends of the socket.
=back
-=head2 IO::POSIX
+=head3 IO::POSIX
Indicates that this object can perform standard posix C<IO>
operations. It implies C<IO::Readable> and C<IO::Writeable>.
@@ -1373,7 +825,7 @@ Gone, see eoi C<IO::Seekable>.
=item IO.fileno
-See C<IO::FileDescriptor>.
+See C<IO::Handle>.
=item /(get|set)(host|net|proto|serv|sock).*/
@@ -1421,9 +873,122 @@ Gone, see C<Path.times>.
=back
-=head1 Additions
+=head2 IO::Buffered
+
+Indicates that this object performs buffering. The management of the
+buffer is completely implementation specific.
+
+=over
+
+=item method flush( --> Bool)
+
+Flushes the buffers associated with this object.
+
+=item method autoflush( --> Bool) is rw
+
+Forces this object to keep its buffers empty
+
+If set to nonzero, forces a flush right away and after every write
+or print on the currently selected output channel.
+Default is 0 (regardless of whether the channel is really buffered
+by the system or not;
+C<$OUT_FH.autoflush> tells you only whether you've asked Perl
+explicitly to flush after each write).
+C<$*OUT> will typically be line buffered if output is to the
+terminal and block buffered otherwise.
+Setting this variable is useful primarily when you are
+outputting to a pipe or socket,
+such as when you are running a Perl program under rsh
+and want to see the output as it's happening.
+This has no effect on input buffering.
+
+
+=back
+
+=head2 IO::Streamable
+
+This role represents objects that depend on some external resource,
+which means that data might not be available at request.
+
+ role IO::Streamable does IO {...}
+
+=over
+
+=item new()
+
+ method new(
+ Bool :$NoOpen,
+ Bool :$Blocking,
+ --> IO::Streamable
+ ) {...}
+
+Unless the NoOpen option is passed, an open will be done on the C<IO> object when it is
+created.
+
+If blocking is passed in, .blocking() is called (see below).
+
+=item method blocking( --> Bool) is rw
+
+This allows the user to control whether this object should do a
+blocking wait or immediately return in the case of not having data
+available.
+
+=item uri
+
+ method uri(Str $uri --> IO::Streamable) {...}
+
+This should be callable on the class, and act like a kind of "new()" function. When given
+a URI, it returns an C<IO::Streamable> of the appropriate type, and throws an error when an
+inappropriate type is passed in. For example, calling C<IO::File.uri('http://....')> will
+throw an error (but will suggest using just uri('http://...') instead).
+
+=back
+
+=head2 IO::Encoded
+
+This is a generic role for encoded data streams.
+
+=over
+
+=item method encoding( --> Str) is rw
+
+=item method locale( --> Str) is rw
+
+Encoding and locale are required for sane conversions.
+
+=back
+
+=head2 IO::Readable::Encoded
+
+This role provides encoded access to a readable data stream, implies
+C<IO::Encoded>. Might imply C<IO::Buffered>, but that's not a requirement.
+
+=over
+
+=over 4
+
+=item uri
+X<uri>X<ftp>X<http>
+
+ method uri(Str $uri --> IO::Streamable);
+ sub uri(Str $uri --> IO::Streamable);
+
+Returns an appropriate C<IO::Streamable> descendant, with the type depending on the uri
+passed in. Here are some example mappings:
+
+ URI type IO type
+ ======== =======
+ file: IO::File or IO::Directory
+ ftp: IO::Socket::INET (data channel)
+ http: IO::Socket::INET
-Please post errors and feedback to perl6-language. If you are making
-a general laundry list, please separate messages by topic.
+These can naturally be overridden or added to by other modules.
+
+=item %*PROTOCOLS dynamic variable
+
+For each protocol, stores a type name that should be instantiated by calling the C<uri>
+constructor on that type, and passing in the appropriate uri.
+
+=back
=for vim:set expandtab sw=4:

0 comments on commit 261003e

Please sign in to comment.