Listen Print

Exegesis 3

Operators

by Damian Conway
October 03, 2001

Editor's note: this document is out of date and remains here for historic interest. See Synopsis 3 for the current design information.

Diamond lives (context-aware);
Underscore space means concatenate; fat comma means pair;
A pre-star will flatten; colon-equals will bind;
And binary slash-slash yields left-most defined.
-- Sade, "Smooth operator" (Perl 6 remix)

In Apocalypse 3, Larry describes the changes that Perl 6 will make to operators and their operations. As with all the Apocalypses, only the new and different are presented -- just remember that the vast majority of operator-related syntax and semantics will stay precisely as they are in Perl 5.

For example...

To better understand those new and different aspects of Perl 6 operators, let's consider the following program. Suppose we wanted to locate a particular data file in one or more directories, read the first four lines of each such file, report and update their information, and write them back to disk.

Related Reading

Programming Perl, 3rd Edition

Programming Perl, 3rd Edition
By Larry Wall, Tom Christiansen, Jon Orwant

We could do that with this:

    sub load_data ($filename ; $version, *@dirpath) {
        $version //= 1;
        @dirpath //= @last_dirpath // @std_dirpath // '.';
        @dirpath ^=~ s{([^/])$}{$1/};
        my %data;
        foreach my $prefix (@dirpath) {
            my $filepath = $prefix _ $filename;
            if (-w -r -e $filepath  and  100 < -s $filepath <= 1e6) {
                my $fh = open $filepath : mode=>'rw' 
                    or die "Something screwy with $filepath: $!";
                my ($name, $vers, $status, $costs) = <$fh>;
                next if $vers < $version;
                $costs = [split /\s+/, $costs];
                %data{$filepath}{qw(fh name vers stat costs)} =
                                ($fh, $name, $vers, $status, $costs);
            }
        }
        return %data;
    }
    my @StartOfFile is const = (0,0);
    sub save_data ( %data) {
        foreach my $data (values %data) {
            my $rest = <$data.{fh}.irs(undef)>
            seek $data.{fh}: *@StartOfFile;
            truncate $data.{fh}: 0;
            $data.{fh}.ofs("\n");
            print $data.{fh}: $data.{qw(name vers stat)}, _@{$data.{costs}}, $rest;
         }
    }
    my %data = load_data(filename=>'weblog', version=>1);
    my $is_active_bit is const = 0x0080;
    foreach my $file (keys %data) {
        print "$file contains data on %data{$file}{name}\n";
        %data{$file}{stat} = %data{$file}{stat} ~ $is_active_bit;
        my @costs := @%data{$file}{costs};
        my $inflation;
        print "Inflation rate: " and $inflation = +<>
            until $inflation != NaN;
        @costs = map  { $_.value }
                 sort { $a.key <=> $b.key }
                 map  { amortize($_) => $_ }
                        @costs ^* $inflation;
        my sub operator:∑ is prec(\&operator:+($)) (*@list : $filter //= undef) {
               reduce {$^a+$^b}  ($filter ?? grep &$filter, @list :: @list);
        }
        print "Total expenditure: $( ∑ @costs )\n";
        print "Major expenditure: $( ∑ @costs : {$^_ >= 1000} )\n";
        print "Minor expenditure: $( ∑ @costs : {$^_ < 1000} )\n";
        print "Odd expenditures: @costs[1..Inf:2]\n"; 
    }
    save_data(%data, log => {name=>'metalog', vers=>1, costs=>[], stat=>0});

I was bound under a flattening star

The first subroutine takes a filename and (optionally) a version number and a list of directories to search:

    sub load_data ($filename ; $version, *@dirpath) {
Note that the directory path parameter is declared as *@dirpath, not @dirpath. In Perl 6, declaring a parameter as an array (i.e @dirpath) causes Perl to expect the corresponding argument will be an actual array (or an array reference), not just any old list of values. In other words, a @ parameter in Perl 6 is like a \@ context specifier in Perl 5.

To allow @dirpath to accept a list of arguments, we have to use the list context specifier -- unary * -- to tell Perl to "slurp up" any remaining arguments into the @dirpath parameter.

This slurping-up process consists of flattening any arguments that are arrays or hashes, and then assigning the resulting list of values, together with any other scalar arguments, to the array (i.e. to @dirpath in this example). In other words, a *@ parameter in Perl 6 is like a @ context specifier in Perl 5.

Pages: 1, 2, 3, 4, 5, 6, 7

Next Pagearrow





Contact Us | Advertise with Us | Privacy Policy | Press Center | Jobs | Submissions Guidelines

Copyright © 2000-2008 O’Reilly Media, Inc. All Rights Reserved. | (707) 827-7000 / (800) 998-9938
All trademarks and registered trademarks appearing on the O'Reilly Network are the property of their respective owners.

For problems or assistance with this site, email