role IO

Input/output related routines

The role provides no methods, but exists so that IO() coercers, which coerce to IO::Path, correctly type-check the resultant value. The role is done by IO::Path and IO::Special.

Routines

sub chdir

Defined as:

sub chdir(IO() $path:$d = True:$r:$w:$x --> IO::Path:D)

Changes value of $*CWD variable to the provided $path, optionally ensuring the new path passes several file tests. NOTE: that this routine does NOT alter the process's current directory (see &*chdir).

Returns IO::Path representing new $*CWD on success. On failure, returns Failure and leaves $*CWD untouched. The $path can be any object with an IO method that returns an IO::Path object. The available file tests are:

By default, only :d test is performed.

chdir         '/tmp'# change $*CWD to '/tmp' and check its .d is True 
chdir :r:w'/tmp'# … check its .r and .w are True 
chdir '/not-there';   # returns Failure 

Note that the following construct is a mistake:

# WRONG! DO NOT DO THIS! 
my $*CWD = chdir '/tmp/';

Use indir instead.

sub &*chdir

Defined as:

PROCESS:<&chdir> = sub (IO() $path --> IO::Path:D)

Changes value of $*CWD variable to the provided $path and sets the process's current directory to the value of $path.absolute. NOTE: that in most cases, you want to use chdir routine instead.

Returns IO::Path representing new $*CWD on success. On failure, returns Failure and leaves $*CWD untouched. The $path can be any object with an IO method that returns an IO::Path object.

Note that unlike regular chdir, there are no arguments to specify which file tests to perform.

&*chdir('/tmp');  # change $*CWD and process's current directory to '/tmp' 
&*chdir('/not-there'); # returns Failure 

Note that the following construct is a mistake:

# WRONG! DO NOT DO THIS! 
my $*CWD = &*chdir('/tmp');

Use the following, instead; or see indir if you do not need to change process's current directory:

temp $*CWD;
&*chdir('/tmp');

sub chmod

Defined as:

sub chmod(Int() $mode*@filenames --> List)

Coerces all @filenames to IO::Path and calls IO::Path.chmod with $mode on them. Returns a List containing a subset of @filenames for which chmod was successfully executed.

chmod 0o755, <myfile1  myfile2># make two files executable by the owner 

sub indir

Defined as:

sub indir(IO() $path&code:$d = True:$r:$w:$x --> Mu)

Takes Callable &code and executes it after locally (to &code) changing $*CWD variable to an IO::Path object based on $path, optionally ensuring the new path passes several file tests. If $path is relative, it will be turned into an absolute path, even if an IO::Path object was given. NOTE: that this routine does NOT alter the process's current directory (see &*chdir). The $*CWD outside of the &code is not affected, even if &code explicitly assigns a new value to $*CWD.

Returns the return value of &code on success. On failure to successfully change $*CWD, returns Failure. WARNING: keep in mind that lazily evaluated things might end up NOT having the $*CWD set by indir in their dynamic scope by the time they're actually evaluated. Either ensure the generators have their $*CWD set or eagerly evaluate them before returning the results from indir:

say indir("/tmp"{
    gather { take ".".IO }
}.CWD# OUTPUT: «(/home/camelia)␤» 
 
say indir("/tmp"{
    eager gather { take ".".IO }
}.CWD# OUTPUT: «(/tmp)␤» 
 
say indir("/tmp"{
    my $cwd = $*CWD;
    gather { temp $*CWD = $cwdtake ".".IO }
}.CWD# OUTPUT: «(/tmp)␤» 

The routine's $path argument can be any object with an IO method that returns an IO::Path object. The available file tests are:

By default, only :d test is performed.

say $*CWD;                   # OUTPUT: «"/home/camelia".IO␤» 
indir '/tmp'{ say $*CWD }# OUTPUT: «"/tmp".IO␤» 
say $*CWD;                   # OUTPUT: «"/home/camelia".IO␤» 
 
indir '/not-there'{;};     # returns Failure; path does not exist 

sub print

Defined as:

multi sub print(**@args --> True)

Prints the given text on standard output (the $*OUT file handle), coercing non-Str objects to Str by calling .Str method:

print "Hi there!\n";   # OUTPUT: «Hi there!␤» 
print "Hi there!";     # OUTPUT: «Hi there!» 
print [123];       # OUTPUT: «1 2 3» 

To print text and include the trailing newline, use put.

sub put

Defined as:

multi sub put(**@args --> True)

Same as print, except appends $*OUT.nl-out (a newline, by default) at the end:

put "Hi there!\n";   # OUTPUT: «Hi there!␤␤» 
put "Hi there!";     # OUTPUT: «Hi there!␤» 
put [123];       # OUTPUT: «1 2 3␤» 

sub say

Defined as:

multi sub say(**@args --> True)

Prints the "gist" of given objects. Same as put, except coerces non-Str arguments using .gist method.

NOTE: the .gist method of some objects, such as Lists, returns only partial information about the object (hence the "gist"). If you mean to print textual information, you most likely want to use put instead.

say Range;        # OUTPUT: «(Range)␤» 
say class Foo {}# OUTPUT: «(Foo)␤» 
say 'I ♥ Perl6';  # OUTPUT: «I ♥ Perl6␤» 
say 1..Inf;       # OUTPUT: «1..Inf␤» 

routine note

Defined as:

method note(Mu: -->Bool:D)
multi sub note(            --> Bool:D)
multi sub note(Str:D $note --> Bool:D)
multi sub note(**@args     --> Bool:D)

Like say, except prints output to $*ERR handle (STDERR). If no arguments are given to subroutine forms, will use string "Noted".

note;       # STDERR OUTPUT: «Noted␤» 
note 'foo'# STDERR OUTPUT: «foo␤» 
note 1..*;  # STDERR OUTPUT: «1..Inf␤» 

sub prompt

multi prompt()
multi prompt($msg)

Prints $msg to $*OUT handle, if $msg was provided, then gets a line of input from $*IN handle. By default, this is equivalent to printing $msg to STDOUT, reading a line from STDIN, removing the trailing new line, and returning the resultant string.

my $name = prompt "What's your name? ";
say "Hi, $name! Nice to meet you!";

sub open

multi sub open(IO() $path|args --> IO::Handle:D)

Creates a handle with the given $path, and calls IO::Handle.open, passing any of the remaining arguments to it. Note that IO::Path type provides numerous methods for reading and writing from files, so in many common cases you do not need to open files or deal with IO::Handle type directly.

my $fh = open :w'/tmp/some-file.txt';
$fh.say: 'I ♥ writing Perl code';
$fh.close;
 
$fh = open '/tmp/some-file.txt';
print $fh.readchars: 4;
$fh.seek: 7SeekFromCurrent;
say $fh.readchars: 4;
$fh.close;
 
# OUTPUT: «I ♥ Perl␤» 

sub slurp

Slurps the contents of the entire file into a Str (or Buf if :bin). Accepts :bin and :enc optional named parameters, with the same meaning as open(). The routine will fail if the file does not exist, or is a directory.

# read entire file as (Unicode) Str 
my $text_contents   = slurp "path/to/file";
 
# read entire file as Latin1 Str 
my $text_contents   = slurp "path/to/file"enc => "latin1";
 
# read entire file as Buf 
my $binary_contents = slurp "path/to/file":bin;

sub spurt

Defined as:

multi spurt(IO() $path|c)

The $path can be any object with an IO method that returns an IO::Path object. Calls IO::Path.spurt on the $path, forwarding any of the remaining arguments.

Options

The encoding with which the contents will be written.

Open the file in binary mode.

Boolean indicating whether to append to a (potentially) existing file. If the file did not exist yet, it will be created. Defaults to False.

Boolean indicating whether to fail if the file already exists. Defaults to False.

Examples

# write directly to a file 
spurt 'path/to/file''default text, directly written';
 
# write directly with a non-Unicode encoding 
spurt 'path/to/latin1_file''latin1 text: äöüß':enc<latin1>;
 
spurt 'file-that-already-exists''some text';           # overwrite file's contents: 
spurt 'file-that-already-exists'' new text':append;  # append to file's contents: 
say slurp 'file-that-already-exists';                    # OUTPUT: «some text new text␤» 
 
# fail when writing to a pre-existing file 
spurt 'file-that-already-exists''new text':createonly;
# OUTPUT: «Failed to open file /home/camelia/file-that-already-exists: file already exists …» 

sub run

sub run(*@args ($*@) --> Proc)

Runs an external command without involving a shell and returns a Proc object.

run 'touch''>foo.txt';
 
run Q:w{rm >foo.txt}# Another way to use run, using word quoting for the 
                      # arguments 

To capture output or error you can use the :out or :err arguments respectively:

my $proc = run 'echo''Perl 6 is Great!':out:err;
with $proc.out { say .get.close } # OUTPUT: «Perl 6 is Great!␤» 
with $proc.err { say .get.close } # OUTPUT: «Nil␤» 

See Proc and Proc::Async for more details.

sub shell

sub shell($cmd --> Proc)

Runs a command through the system shell. All shell meta characters are interpreted by the shell, including pipes, redirects, environment variable substitutions and so on. Shell escapes are a severe security concern and can cause confusion with unusual file names. Use run if you want to be safe.

The return value is of type Proc.

shell 'ls -lR | gzip -9 > ls-lR.gz';

See Proc for more details, for example on how to capture output.

Related classes

See also the related classes IO::Handle and IO::Path.

Type Graph

Type relations for IO
perl6-type-graph IO IO Mu Mu Any Any Any->Mu IO::Special IO::Special IO::Special->IO IO::Special->Any Cool Cool Cool->Any IO::Path IO::Path IO::Path->IO IO::Path->Cool IO::Path::Win32 IO::Path::Win32 IO::Path::Win32->IO::Path IO::Path::Unix IO::Path::Unix IO::Path::Unix->IO::Path IO::Path::Cygwin IO::Path::Cygwin IO::Path::Cygwin->IO::Path IO::Path::QNX IO::Path::QNX IO::Path::QNX->IO::Path

Stand-alone image: vector