class IO::Handle

Opened file or stream

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


method get

Reads a single line from the input stream (usually the Standard Input or a file).

Read one line from the standard input:


Read one line from a file:

my $fh = open 'filename';
my $line = $fh.get;

method getc

Read a single character from the input stream.

method eof

Returns Bool::True if the read operations have exhausted the content of the file.

method lines

method lines($limit = Inf)

Return a lazy list of the file's lines read via get, limited to $limit lines.

    my @data;
    my $data-file = open 'readings.csv'
    for $data-file.lines -> $line {

method print

method print(*@text --> Bool)

Text writing; writes the given @text to the filehandle.

my $fh = open 'path/to/file', :w;
$fh.print("some text\n");

method read

method read(IO::Handle:D: Int(Cool:D) $bytes --> Blob)

Binary reading; reads and returns $bytes bytes from the handle

method write

method write(IO::Handle:D: Blob:D $buf)

Binary writing; writes $buf to the filehandle.

method seek

method tell

method slurp

method spurt

method close

Will close a previously opened filehandle.


Related roles and classes

See also the related role IO and the related classes IO::FileTestable and IO::Path.

Type graph

Below you should see a clickable image showing the type relations for IO::Handle that links to the documentation pages for the related types. If not, try the PNG version instead.

perl6-type-graph IO::Handle IO::Handle Any Any IO::Handle->Any IO IO IO::Handle->IO Mu Mu Any->Mu IO::ArgFiles IO::ArgFiles IO::ArgFiles->IO::Handle

Routines supplied by role IO

IO::Handle does role IO, which provides the following methods:

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?";


Hi there!How are you?

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

sub say

Print the given text, followed by a newline "\n" on $*OUT (standard output).

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?";


Hi there!
How are you?

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;       # 1 2 3 4␤
    say @array.gist;  # 1 2 3 4␤

    my %hash = "a" => 1, "b" => 2, "c" => 3;
    say %hash;        # a => 1, b => 2, c => 3␤
    say %hash.gist;   # 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 dd

The Tiny Data Dumper. This function takes the input list of variables and notes them (on $*ERR) in an easy to read format, along with the name of the variable. Thus,

my $a = 42;
my %hash = "a" => 1, "b" => 2, "c" => 3;
dd %hash, $a;


%hash = ("a" => 1, "c" => 3, "b" => 2).hash, $a = 42

to the standard error stream.

This is in spirit similar to Perl 5's Data::Dumper module.

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, :$chomp)

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

File mode options

  • read-only mode, :r

  • 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
    spurt $fh, "new text\n";
    Failed to write bytes to filehandle: bad file descriptor
  • write-only mode, :w

  • 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);
    spurt $fh, "stuff\n";
    spurt $fh, "more stuff\n";
    $, 0);   # return to the start of the file
    $fh.get();        # Reading from filehandle failed: bad file descriptor
  • read-write mode, :rw

  • 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", :w);
  • append mode, :a

  • 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

  • binary mode, :bin

  • 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.

  • text mode encoding, :enc

  • 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 "Unicode", which implies figuring out which actual UTF is in use, either from a BOM or other heuristics. If heuristics are inconclusive, UTF-8 will be assumed. (No 8-bit encoding will ever be picked implicitly.) There exists no valid option with the name "Unicode", so the following will result in an error:

    my $fh = open("path/to/file", enc => "Unicode");

    This is because one needs to specify a specific unicode encoding, e.g. "utf8".

    Newline options

  • end-of-line (EOL) marker, :nl

  • The marker used to indicate the end of a line of text. Only used in text mode. Defaults to "EOL", which implies accepting any combination of "\n", "\r\n" or "\r" or any other Unicode character that has the Zl (Separator, Line) property.

    # explicitly use CR-LF as EOL character
    my $fh = open("path/to/file", nl => "\r\n");
  • chomp mode, :chomp

  • 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

    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.

    sub dir

    sub dir(Cool $path = '.', Mu :$test = none('.', '..'))

    Returns a list of IO::File and IO::Path objects for the files and directories found in the $path. If $path is not given assumes the current directory.

    A second optional parameter can be given that will be matched against the strings to filter out certain entries. By default it filters out the '.' and '..' entries.


    for dir() -> $file {
       say $file;

    To include all the entries (including . and ..) write:

    dir(test => all())

    To include only entries with a .pl extension write:

    dir(test => /.pl$/)

    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        = $*ENC,
        Bool :append      = False,
        Bool :$createonly = False,
        --> Bool ) is export

    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:


  • :enc

  • The encoding with which the contents will be written.

  • :append

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

  • :createonly

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


    # 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;
    File 'test' already exists, and :createonly was specified

    sub mkdir

    multi sub mkdir(Int:D $mode, *@dirnames, :$CWD = $*CWD);
    multi sub mkdir($path, $mode = 0o777, :$CWD = $*CWD);

    Creates one or more directories with the permissions specified as an integer (thought still subject to umask).

    Throws an exception of type X::IO::Mkdir if the directory cannot be created.

    sub rmdir

    sub rmdir($dir as IO --> Bool) is export

    Remove the given directory if it is empty.

    Returns True on success. Throws an exception of type X::IO::Rmdir if the directory cannot be removed (e.g. the directory is not empty, or the path is not a directory).

    sub run

    sub run(*@args ($, *@)) returns Proc::Status:D

    Runs an external command without involving a shell (if possible). Expects the command and each of its command line arguments as a list.

    The return value is of type Proc::Status.

    run 'systemctl', 'restart', 'apache2'

    Arguments are not subject to shell expansions, shell variable interpolation or other shenanigans. See shell if you want that.

    sub shell

    sub shell($cmd) returns Proc::Status:D

    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. See run if you don't want that.

    The return value is of type Proc::Status.

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

    Routines supplied by class Any

    IO::Handle inherits from class Any, which provides the following methods:

    method ACCEPTS

    multi method ACCEPTS(Any:D: Mu $other)

    Returns True if $other === self (i.e. it checks object identity).

    Many built-in types override this for more specific comparisons

    method any

    method any() returns Junction:D

    Interprets the invocant as a list and creates an any-Junction from it.

    say so 2 == <1 2 3>.any;        # True
    say so 5 == <1 2 3>.any;        # False

    method all

    method all() returns Junction:D

    Interprets the invocant as a list and creates an all-Junction from it.

    say so 1 < <2 3 4>.all;         # True
    say so 3 < <2 3 4>.all;         # False

    method one

    method one() returns Junction:D

    Interprets the invocant as a list and creates an one-Junction from it.

    say so 1 == (1, 2, 3).one;      # True
    say so 1 == (1, 2, 1).one;      # False

    method none

    method none() returns Junction:D

    Interprets the invocant as a list and creates an none-Junction from it.

    say so 1 == (1, 2, 3).none;     # False
    say so 4 == (1, 2, 3).none;     # True

    method list

    Interprets the invocant as a list, and returns that List.

    say so 42.list.^name;           # List
    say so 42.list.elems;           # 1

    method flat

    Interprets the invocant as a list, flattens it, and returns that list.

    say ((1, 2), (3)).elems;        # 2
    say ((1, 2), (3)).flat.elems;   # 3

    method eager

    Interprets the invocant as a list, evaluates it eagerly, and returns that list.

    say (1..10).eager;              # 1 2 3 4 5 6 7 8 9 10

    method elems

    Interprets the invocant as a list, and returns the number of elements in the list.

    say 42.elems;                   # 1
    say <a b c>.elems;              # 3

    method end

    Interprets the invocant as a list, and returns the last index of that list.

    say 6.end;                      # 0
    say <a b c>.end;                # 2

    method pairup

    method pairup() returns List

    Interprets the invocant as a list, and constructs a list of pairs from it, in the same way that assignment to a Hash does. That is, it takes two consecutive elements and constructs a pair from them, unless the item in the key position already is a pair (in which case the pair is passed is passed through, and the next list item, if any, is considered to be a key again).

    say (a => 1, 'b', 'c').pairup.perl;     # ("a" => 1, "b" => "c").list

    sub exit

    sub exit(Int() $status = 0)

    Exits the current process with return code $status.

    Routines supplied by class Mu

    IO::Handle inherits from class Mu, which provides the following methods:

    routine defined

    multi sub    defined(Mu) returns Bool:D
    multi method defined()   returns Bool:D

    Returns False on the type object, and True otherwise.

    say Int.defined;                # False
    say 42.defined;                 # True

    Very few types (like Failure) override defined to return False even for instances:

    sub fails() { fail 'oh noe' };
    say fails().defined;            # False

    routine Bool

    multi sub    Bool(Mu) returns Bool:D
    multi method Bool()   returns Bool:D

    Returns False on the type object, and True otherwise.

    Many built-in types override this to be False for empty collections, the empty string or numerical zeros

    say Mu.Bool;                    # False
    say;                # True
    say [1, 2, 3].Bool;             # True
    say [].Bool;                    # False
    say { 'hash' => 'full'}.Bool;   # True
    say {}.Bool;                    # False

    method Str

    multi method Str()   returns Str

    Returns a string representation of the invocant, intended to be machine readable. Method Str warns on type objects, and produces the empty string.

    say Mu.Str;                     #!> use of uninitialized value of type Mu in string context

    routine gist

    multi sub    gist(Mu) returns Str
    multi method gist()   returns Str

    Returns a string representation of the invocant, optimized for fast recognition by humans.

    The default gist method in Mu re-dispatches to the perl method for defined invocants, and returns the type name in parenthesis for type object invocants. Many built-in classes override the case of instances to something more specific.

    gist is the method that say calls implicitly, so say $something and say $something.gist generally produce the same output.

    say Mu.gist;        # (Mu)
    say;    #

    routine perl

    multi sub    perl(Mu) returns Str
    multi method perl()   returns Str

    Returns a Perlish representation of the object (i.e., can usually be re-evaluated with EVAL to regenerate the object). The exact output of perl is implementation specific, since there are generally many ways to write a Perl expression that produces a particular value

    method clone

    method clone(*%twiddles)

    Creates a shallow clone of the invocant. If named arguments are passed to it, their values are used in every place where an attribute name matches the name of a named argument.

    class Point2D {
        has ($.x, $.y);
        multi method gist(Point2D:D:) {
            "Point($.x, $.y)";
    my $p = => 2, y => 3);
    say $p;                     # Point(2, 3)
    say $p.clone(y => -5);      # Point(2, -5)

    method new

    multi method new(*%attrinit)

    Default method for constructing (create + initialize) new objects of a class. This method expects only named arguments which are then used to initialize attributes with accessors of the same name.

    Classes may provide their own new method to override this default.

    new triggers an object construction mechanism that calls submethods named BUILD in each class of an inheritance hierarchy, if they exist. See the documentation on object construction for more information.

    method bless

    method bless(*%attrinit) returns Mu:D

    Lower-level object construction method than new.

    Creates a new object of the same type as the invocant, uses the named arguments to initialize attributes, and returns the created object.

    You can use this method when writing custom constructors:

    class Point {
        has $.x;
        has $.y;
        multi method new($x, $y) {
            self.bless(:$x, :$y);
    my $p =, 1);

    (Though each time you write a custom constructor, remember that it makes subclassing harder).

    method CREATE

    method CREATE() returns Mu:D

    Allocates a new object of the same type as the invocant, without initializing any attributes.

    say Mu.CREATE.defined;  # True

    method print

    multi method print() returns Bool:D

    Prints value to $*OUT after stringification using .Str method without adding a newline at end.

    "abc\n".print;          # abc

    method say

    multi method say() returns Bool:D

    Prints value to $*OUT after stringification using .gist method with newline at end.

    say 42;                 # 42

    method ACCEPTS

    multi method ACCEPTS(Mu:U: $other)

    ACCEPTS is the method that smart matching with the infix ~~ operator and given/when invokes on the right-hand side (the matcher).

    The Mu:U multi performs a type check. Returns True if $other conforms to the invocant (which is always a type object or failure).

    say 42 ~~ Mu;           # True
    say 42 ~~ Int;          # True
    say 42 ~~ Str;          # False

    Note that there is no multi for defined invocants; this is to allow autothreading of junctions, which happens as a fallback mechanism when no direct candidate is available to dispatch to.

    method WHICH

    multi method WHICH() returns ObjAt:D

    Returns an object of type ObjAt which uniquely identifies the object. Value types override this method which makes sure that two equivalent objects return the same return value from WHICH.

    say 42.WHICH eq 42.WHICH;       # True

    method WHERE

    method WHERE() returns Int

    Returns an Int representing the memory address of the object.

    method WHY

    multi method WHY()

    Returns the attached Pod value. For instance,

        sub cast(Spell $s)
        #= Initiate a specified spell normally
        #= (do not use for class 7 spells)
        say &cast.WHY;


    Initiate a specified spell normally (do not use for class 7 spells)

    See the documentation specification for details about attaching Pod to variables, classes, functions, methods, etc.

    trait is export

    multi sub trait_mod:<is>(Mu:U \type, :$export!)

    Marks a type as being exported, that is, available to external users.

    my class SomeClass is export { }

    A user of a module or class automatically gets all the symbols imported that are marked as is export.

    method take

    method take()

    Takes the given item and passes it to the enclosing gather block.

    #| randomly select numbers for lotto
    my $num-selected-numbers = 6;
    my $max-lotto-numbers = 49;
    gather for ^$num-selected-numbers {
        take (1 .. $max-lotto-numbers).pick(1);
    }.say;    #-> 32 22 1 17 32 9  (for example)