class IO::Special

Path to Special I/O device

class IO::Special does IO { }

Used as a $.path attribute in filehandles for special standard input $*IN and output $*OUT and $*ERR. Provides a bridged interface of IO::Handle, mostly file tests and stringification.

Methods

method new

method new(:$!what!)

Takes a single required attribute what. It is unlikely that you will ever need to construct one of these objects yourself.

method what

say $*IN.path.what;  # OUTPUT: «<STDIN>␤» 
say $*OUT.path.what# OUTPUT: «<STDOUT>␤» 
say $*ERR.path.what# OUTPUT: «<STDERR>␤» 

Returns one of the strings '<STDIN>', '<STDOUT>', or '<STDERR>', specifying the type of the special IO device.

method WHICH

method WHICH(IO::Special:D: --> Str)

This returns a string that identifies the object. The string is composed by the type of the instance (IO::Special) and the what attribute:

$*IN.path.what;  # OUTPUT: «<STDIN>␤» 
$*IN.path.WHICH# OUTPUT: «IO::Special<STDIN>␤» 

method Str

method Str(IO::Special:D:)

This returns '<STDIN>', '<STDOUT>', or '<STDERR>' as appropriate.

method IO

method IO(IO::Special:D: --> IO::Special)

Returns the invocant.

say $*IN.path.IO.what;  # OUTPUT: «<STDIN>␤» 
say $*IN.path.what;     # OUTPUT: «<STDIN>␤» 

method e

method e(IO::Special:D: --> True)

The 'exists' file test operator, always returns True.

method d

method d(IO::Special:D: --> False)

The 'directory' file test operator, always returns False.

method f

method f(IO::Special:D: --> False)

The 'file' file test operator, always returns False.

method s

method s(IO::Special:D: --> 0)

The 'size' file test operator, always returns 0.

method l

method l(IO::Special:D: --> False)

The 'symbolic links' file test operator, always returns False.

method r

method r(IO::Special:D: --> Bool)

The 'read access' file test operator, returns True if and only if this instance represents the standard input handle(<STDIN>).

method w

method w(IO::Special:D: --> Bool)

The 'write access' file test operator, returns True only if this instance represents either the standard output (<STOUT>) or the standard error (<STDERR>) handle.

method x

method x(IO::Special:D: --> False)

The 'execute access' file test operator, always returns False.

method modified

method modified(IO::Special:D: --> Instant)

The last modified time for the filehandle. It always returns an Instant type object.

method accessed

method accessed(IO::Special:D: --> Instant)

The last accessed time for the filehandle. It always returns an Instant type object.

method changed

method changed(IO::Special:D: --> Instant)

The last changed time for the filehandle. It always returns an Instant type object.

method mode

method mode(IO::Special:D: --> Nil)

The mode for the filehandle, it always returns Nil

Type Graph

Type relations for IO::Special
perl6-type-graph IO::Special IO::Special Any Any IO::Special->Any IO IO IO::Special->IO Mu Mu Any->Mu

Expand above chart

Routines supplied by role IO

IO::Special does role IO, which provides the following routines:

(IO) sub mkdir

Defined as:

sub    mkdir(IO() $pathInt() $mode = 0o777 --> IO::Path:D)

Creates a new directory; see mode for explanation and valid values for $mode. Returns the IO::Path object pointing to the newly created directory on success; fails with X::IO::Mkdir if directory cannot be created.

Also creates parent directories, as needed (similar to *nix utility mkdir with -p option); that is, mkdir "foo/bar/ber/meow" will create foo, foo/bar, and foo/bar/ber directories if they do not exist, as well as foo/bar/ber/meow.

(IO) 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:

  • :d — check .d returns True

  • :r — check .r returns True

  • :w — check .w returns True

  • :x — check .x returns True

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

    (IO) 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');

    (IO) 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 

    (IO) 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:

  • :d — check .d returns True

  • :r — check .r returns True

  • :w — check .w returns True

  • :x — check .x returns True

  • 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 

    (IO) sub print

    Defined as:

    multi sub print(**@args --> True)
    multi sub print(Junction:D --> True)

    Prints the given text on standard output (the $*OUT filehandle), coercing non-Str objects to Str by calling .Str method. Junction arguments autothread and the order of printed strings is not guaranteed.

    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.

    (IO) sub put

    Defined as:

    multi sub put(**@args --> True)
    multi sub put(Junction:D --> True)

    Same as print, except it uses print-nl (which prints a newline, by default) at the end. Junction arguments autothread and the order of printed strings is not guaranteed.

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

    (IO) sub say

    Defined as:

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

    Prints the "gist" of given objects. Same as put, except uses .gist method to obtain string representation of the object.

    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␤» 

    (IO) 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␤» 

    (IO) sub prompt

    multi sub prompt()
    multi sub 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. As of Rakudo 2018.08, prompt will create allomorphs for numeric values, equivalent to calling val prompt.

    my $name = prompt "What's your name? ";
    say "Hi, $name! Nice to meet you!";
    my $age = prompt("Say your age (number)");
    my Int $years = $age;
    my Str $age-badge = $age;

    In the code above, $age will be duck-typed to the allomorph IntStr if it's entered corectly as a number.

    (IO) 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␤» 

    (IO) sub slurp

    Defined as:

    multi sub slurp(IO::Handle:D $fh = $*ARGFILES|c)
    multi sub slurp(IO() $path|c)

    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(); possible encodings are the same as in all the other IO methods and are listed in encoding routine. The routine will fail if the file does not exist, or is a directory. Without any arguments, sub slurp operates on $*ARGFILES, which defaults to $*IN in the absence of any filenames.

    # 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;

    (IO) 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

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

    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 …» 

    (IO) sub shell

    sub shell($cmd --> Proc)

    Runs a command through the system shell, which defaults to %*ENV<ComSpec> /c in Windows, /bin/sh -c otherwise. 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.