role IO

Input/output related object

role IO { }

The IO role provides no functionality itself; it simply marks that a particular object relates to input/output.

Please note that coercion via Cool.IO leads to IO::Path. This is the exception from the rule.

Routines

sub print

Print the given text on $*OUT (standard output), e.g.:

print "Hi there!\n";   # Hi there! 

Note that the print function does not (in contrast to some other languages) append a newline character to the text. Thus the following code

print "Hi there!";
print "How are you?";
print (0..101).list;

displays

Hi there!How are you?0123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101

To print text implicitly including the trailing newline character, use say.

sub put

Print the given text on $*OUT (standard output) with appended $*OUT.nl-out. The default for the latter is the platform dependent newline sequence.

put 'Merry 1.0!';
put (0..101).list;

outputs

Merry 1.0!
0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101

sub say

Print the given text in human readable form, followed by a $*OUT.nl-out (platform dependent newline) on $*OUT (standard output). Long output may be truncated. For machine readable output use put.

With say, the example code as mentioned in the print section will be displayed as the user likely intended:

say "Hi there!";
say "How are you?";
say (0..101).list;

displays

Hi there!
How are you?
(0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 ...)␤

say prints non-Str objects by calling their .gist method before printing. Hence the following say statements for the respective containers are equivalent:

my @array = qw{1 2 3 4};
say @array;       # OUTPUT: «[1 2 3 4]␤» 
say @array.gist;  # OUTPUT: «[1 2 3 4]␤» 
 
my %hash = "a" => 1"b" => 2"c" => 3;
say %hash;        # OUTPUT: «{a => 1, b => 2, c => 3}␤» 
say %hash.gist;   # OUTPUT: «{a => 1, b => 2, c => 3}␤» 

sub note

Print the given text, followed by a newline "\n" on $*ERR (standard error). Before printing, call the .gist method on any non-Str objects.

note is effectively say, only it writes its output to the standard error stream. For instance:

if ("path/to/pirate/treasure".IO.e{
    say "Found pirate treasure!";
}
else {
    note "Could not find pirate treasure.  Are you sure it exists?";
}

will report (on the standard output stream) that treasure has been found if it exists or will note on the error stream that it couldn't be found if it doesn't exist.

sub prompt

sub prompt($msg)

Prints $msg to standard output and waits for the user to type something and finish with an ENTER. Returns the string typed in without the trailing newline.

my $name = prompt("Hi, what's your name? ");

sub open

my $fh = open(IO::Path() $path:$r:$w:$a:$rw,
              :$bin:$enc:$nl-in:$nl-out:$chomp)

Opens the $path (by default in text mode) with the given options, returning an IO::Handle object.

File mode options

Open the file as read only, e.g.:

my $fh = open("path/to/file":r);

This is the default mode for open.

Write-related methods on the returned IO::Handle object will fail in this mode:

my $fh = open("test");   # the file "test" already exists 
$fh.print("new text\n"); # fails 
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::AdHoc: Failed to write bytes to filehandle: bad file descriptor␤» 

Open the file for writing, creating it if it doesn't exist or overwriting the file if it does exist, e.g.:

my $fh = open("path-to-file":w);

Read-related methods will fail in this mode:

my $fh = open("test":w);
$fh.print("stuff\n");
$fh.print("more stuff\n");
$fh.seek(0);      # return to the start of the file 
$fh.get();        # fails 
CATCH { default { put .^name''.Str } };
# OUTPUT: «Reading from filehandle failed: bad file descriptor␤» 

Open the file for reading and writing, creating the file if it doesn't exist or overwriting the file if it already exists.

my $fh = open("path-to-file":rw);

Open the file for appending. If the file does not exist, create it. If the file already exists, append data to it.

my $fh = open("path-to-file":a);

Encoding options

Open the file in binary mode (byte mode):

my $fh = open("path-to-file":bin);

A file opened with :bin may still be processed line-by-line, but IO will be in terms of Buf rather than Str types. Default is False, implying text semantics.

The encoding to use if opened in text mode.

# open explicitly as utf8 
my $fh = open("path-to-file"enc => "utf8");
my $fh = open("path-to-file"enc => "utf-8");  # this form also works 
# open with latin1 encoding 
my $fh = open("path-to-file"enc => "latin1");

Defaults to "utf8".

Newline options

nl-in is the marker used to indicate the end of a line of text. Only used in text mode. Defaults to ["\n", "\r\n"] and does not include "\r". nl-out defaults to "\n".

# explicitly use CR-LF as EOL character 
my $fh = open("path-to-file"nl-in => "\r\n");

Whether or not to remove newline characters from text obtained with .lines and .get. Defaults to True.

# don't remove newline characters from input 
my $fh = open("path-to-file"chomp => False);
say $fh.get();     # returns line including newline char 

method close

To close an open file handle, simply call its close method:

my $fh = open("path-to-file");
# ... do stuff with the file 
$fh.close;

It is also possible to call this as a sub, thus the example above can be written equivalently like so:

my $fh = open("path-to-file");
# ... do stuff with the file 
close $fh;

When a file was opened for writing, closing it is important to ensure that all contents are actually written to the file. You may want to consider using a LEAVE phaser to guard against exceptions in your code that could prevent your program from reaching the line with $fh.close.

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

sub spurt($where$what,
    Str  :$enc        = 'utf8',
    Bool :$bin        = False,
    Bool :$append      = False,
    Bool :$createonly = False
    --> Bool )

Writes the indicated contents (2nd positional parameter, $what) to the location indicated by the first positional parameter, $where (which can either be a string or an IO::Path object). To write to an IO::Handle, use the print method.

If a file needs to be opened for writing, it will also be closed. Returns True on success, or the appropriate Failure if something went wrong.

These named parameters are optional and only have meaning if the first positional parameter was not an IO::Handle:

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"; 
 
# append to a pre-existing file 
#spurt "file_already_exists", "some text"; 
#spurt "file_already_exists", "new text", :append; 
#slurp "file_already_exists";   # some text␤new text 
 
# fail when writing to a pre-existing file 
#spurt "file_already_exists", "new text", :createonly; 
CATCH { default { put .^name''.Str } };
# OUTPUT: «X::Cannot::Empty: Cannot pop from an empty Array␤» 

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 you can use the :out argument:

my $proc = run 'echo''Perl 6 is Great!':out;
say $proc.out.get# OUTPUT: Perl 6 is Great! 

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::Handle IO::Handle IO::Handle->IO IO::Handle->Any IO::Socket IO::Socket IO::Socket->IO IO::Pipe IO::Pipe IO::Pipe->IO::Handle IO::ArgFiles IO::ArgFiles IO::ArgFiles->IO::Handle IO::Socket::INET IO::Socket::INET IO::Socket::INET->Any IO::Socket::INET->IO::Socket

Stand-alone image: vector