This is an advance chapter of Learning Perl 6 by Randal L. Schwartz and brian d foy. It is incomplete and may contain merely notes or an outline for future work. It may also contain sections of their writing from other sources, although these are noted where possible.

This work is copyrighted under a contract between O'Reilly Media and the authors, and you cannot repost it or distribute it without permission.

Working with files

File meta-information

File tests let us get information about files without actually doing anything to them. Perhaps we want to check to see if a filename already exists before we do something, or find out the file size. Each file test operator answers a different question about the meta-information about a file.

To ask a question about a file, we use the smart match operater, <~~> to apply the file test operator to the filename:


$filename ~~ FILE_TEST_OPERATOR;

Each file test operator begins with a colon and has a letter the indicates the actual test. Table XXX show the complete list of file test operators and the question they answer. Most of these operators return true or false, but a few of them return extra information (such as :s, which returns the file size in bytes).

To test if a file is readable, we use the :r operator. Most file test operators return either true or false, so we can use them in the condition for a control structure:


if $filename ~~ :r {
    say "$filename is readable";
    }
else {
    say "$filename is not readable";
    }

If we want to ask multiple questions about a file at the same time, we can combine the file test operators with a junction. We combine the :r, :w, and :x with the & (AND junction) to make a single test to check if the file in $filename is readable, writeable, and executable at the same time:


if $filename ~~ :r & :w & :x  {
    say "$filename is readable, writeable, and exectable";
    }

We can also use the object-oriented style using the TEST method, which we pass a list of file test operators:


if $filename.TEST(:r, :w) {
    say "$filename is readable and writeable";
    }
    
=row

We can group the file test operators into several groups, as shown in Table XXX.

=row =cell Permissions =cell effective user :r :w :x :o real user :R :W :X :O :u :g :K

The "permissions" group might not apply to every operating system[1]. The effective user is the identity of the person (or account) running our script. This is different from the real user because XXX. For instance, the root user (the real user) may run some commands as george (the effective user). To find out if the file is readable by george, we need the :r with the lowercase r.

The "types" group tells us what sort of file we have. Although most people think of files as a document that they edit and save, operating systems just see them as groups of data on the disk. As such, a directory is a file too, because it's a list of filenames (the items in the directory) stored on the disk. These aren't mutually exclusive either. A symbolic link returns true for :l, but if that link also points to a directory, it returns true for :d too.

The :T and :B operators look at the file's contents and try to guess if the file is a pure text file (such as a shopping list) or a binary file (such as an image). The opertars look at the first part of the file and based on what it sees, makes its guess. These operators are nearly opposites, so almost in all cases they give opposite answers. The trivial case, where the file is empty, means both :T and :B return false.


#!/usr/local/bin/pugs


my $start_dir = @*ARGS[0] // '.';


my $dh = opendir $start_dir err die "Could not open $start_dir!";
my @files = $dh.readdir;
$dh.closedir;


for @files -> $file {
    next if $file ~~ /^\./; # skip the hidden files
    printf "%-70s  %s  %s  %s\n",
        $file,
        $file ~~ :r ?? 'x' !! '',
        $file ~~ :w ?? 'x' !! '',
        $file ~~ :x ?? 'x' !! '';		
    }
    
    

File meta information

* stat buffers

Bitwise operators

* do we even need to cover this?