=encoding utf8 =head1 TITLE Synopsis 16: I/O =head1 VERSION Created: 12 Sep 2006 Last Modified: 5 Nov 2014 Version: 28 Many of these functions will work as in Perl 5, except we're trying to rationalize everything into roles. For now you can assume most of the important functions will automatically be in the * namespace. However, with IO operations in particular, many of them are really methods on an IO handle, and if there is a corresponding global function, it's merely an exported version of the method. =head1 IO =head2 Overridable IO handles In Perl 6, there are the I IO handles, and any number of overriding inner filehandles for the same symbol. The I handles are our old familiar friends (with new names). Standard input changed from STDIN to C<$*IN>, standard output changed from STDOUT to C<$*OUT>, and standard error changed from STDERR to C<$*ERR>. In Perl 6 these symbols represent more of a concept than a given filehandle, since the meaning is contextually determined. The process's version of these handles live in the C namespace, which is more global than the per-interpreter C namespace. When no explicit filehandle is used, the standard IO operators are defined in terms of the dynamic variables. So the C function prints to C<$*OUT>, while C prints to C<$*ERR>. The C 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 any of those filehandles within the dynamic scope of itself and of its called routines. So to put it another way, when you write something like say "Howdy, world!" the C function looks for the current meaning of C<$*OUT>, and takes the closest definition it can find in its callers. If none of the callers have overridden the definition, it looks in the interpreter's C namespace. If the interpreter hasn't overridden the meaning, it takes the meaning from C. In essence, any dynamic scope in Perl 6 is allowed to do IO redirection much like a Unix shell does with its subprocesses, albeit with a different syntax: { my $*OUT will leave *.close = open $newfile, :w; say "Written to $newfile"; } # stdout reverts to outer scope's definition, and closed the file In short: default handle routine for sub form purpose ======= =========== ======= print $*OUT string-based writing say $*OUT string-based writing get $*ARGFILES read a line (Str) lines $*ARGFILES read all lines (Str) words $*ARGFILES read all words (Str) read binary reading (Buf) write binary writing (Buf) =head2 Path Names and the .IO coercer Path names are just strings (C). Methods that return path names, will just return strings. As soon as you need to do manipulation on the path name (e.g. to find out its C or C), you can create an C object out of the string by applying the C<.IO> coercer: my $path = $filename.IO; Then you can use any of the C methods, such as C: my $handle = $newfile.IO.open(:w); Note that the C sub, is just really syntactic sugar for the above: my $handle = open $newfile, :w; =head2 $*SPEC The current system's path semantics are encapsulated in C<$*SPEC> dynamic variable. It adheres to the C interface, and is automatically 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; ... # your code } # original path semantics here again Please note that it does B need to be an instantiated object: the standard C 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 class. =head2 $*CWD and chdir() The dynamic variable $*CWD is an C object representing the current working directory. It is normally set with the C function, which will check whether the specified path exists as a directory and is accessible (C<-x>). chdir($dir); # sets $*CWD of scope, usually PROCESS::<$CWD> The C function returns a C Failure if the path does not exist, or is not a directory, or is not accessible. Otherwise returns a newly created C object (which will be C). Please note that the path in C<$*CWD> does not have any bearing on what the underlying operating system's concept of a "current directory". It is simply the path that will prepended before any implicit or explicit relative paths, and the default path that will be used when executing a sub-process. To be changing C<$*CWD> just for a given scope, you can use C: indir $dir, { ... your code in $dir ... }; ... your code in $*CWD again ... or you can use C with a temporary C<$*CWD>: { temp $*CWD = chddir($dir); ... your code in $dir ... } ... your code in $*CWD again ... =head2 $*TMPDIR and tmpdir() The dynamic variable C<$*TMPDIR> is an C object which points to the system's directory for temporary files. It can be set with the C function which will check whether the specified path exists as a directory and has complete access (C<+rwx>). tmpdir($dir); # sets $*TMPDIR of scope, usually PROCESS::<$TMPDIR> To set a locally scoped version of C<$*TMPDIR>, you can use C with a temporary C<$*TMPDIR>: { temp $*TMPDIR = $tmpdir($dir); ... your code with $*TMPDIR being $dir ... } ... your code in original $*TMPDIR again ... It will return a newly created C object (which is C) or an appropriate C. The initialization of C<$*TMPDIR> at startup is set depending on the OS you're on. =head2 $*HOME and homedir() The dynamic variable C<$*HOME> is an C object which points to the user's home directory. It can be set with the C function which will check whether the specified path exists as a directory and is completely accessible (C<+rwx>). homedir($dir); # sets $*HOME of scope, usually PROCESS::<$HOME> To set a locally scoped version of C<$*HOME>, you can use C with a temporary C<$*HOME>: { temp $*HOME = homedir($dir); ... your code with $*HOME being $dir ... } ... your code in original $*HOME again ... It will return a newly created C object (which is C) or an appropriate C. The initialization of C<$*HOME> at startup is set depending on the OS you're on. =head2 System dependent path semantics and IO::Spec Each time an C object is created, the current C<$*SPEC> will be encapsulated in the object, to be used for all path related operations. Of course, it is also possible to specify a specify a specific system's path semantics module when creating an C object with the C<:SPEC> named parameter: my $SPEC = IO::Spec::Win32; my $path = $fileonNTFS.IO(:$SPEC); or: my $path = $fileonNTFS.IO(:SPEC); # auto-expand to IO::Spec::Win32 =head2 Functions and Classes The functions and classes that define most of the functionality for IO are more thoroughly defined in S32-setting-library/IO.pod. The main functions used are listed in S29 with references to S32-setting-library/IO.pod. An overview: =head3 Functions print(@text) # print text on $*OUT say(@text) # print text + newline on $*OUT note(@text) # print text + newline on $*ERR dd($a,$b,$c) # tiny data dumper on $*ERR $line = prompt($message) # print message on $*OUT, obtain next line $handle = open($path) # open a file, return IO::Handle @paths = dir # paths (as IO::Path) in $*CWD @paths = dir($dir) # paths (as IO::Path) in $dir $contents = slurp($handle) # read all that's left of an opened filehandle $contents = slurp($filename) # read all from given filename spurt($handle,$contents) # write $contents to $handle spurt($filename,$contents) # write $contents to $filename mkdir($dir) # create a directory rmdir($dir) # remove a directory mkpath($path) # create directory and parents as appropriate chdir($dir) # set $*CWD temp $*CWD = chdir($dir) # set $*CWD for the current scope indir($dir, { ... }) # execute code with temporary $*CWD ... }; tmpdir($dir) # set $*TMPDIR temp $*TMPDIR = tmpdir($dir) # set $*TMPDIR for the current scope homedir($dir) # set $*HOME temp $*HOME = homedir($dir) # set $*HOME for the current scope copy($from,$to) # copy a file rename($from,$to) # rename (move) a file on same physical storage move($from,$to) # move (rename) a file to other storage unlink(*@files) # remove one or more files chmod($permission,*@files) # change permissions of one or more files link($target,$source) # create a hard-link to a file symlink($target,$source) # create a symbolic link to a file =head3 IO::Spec Class The C itself only has one method: C