Perl5 -> Perl6: read and write to files


A real common task in my day-to-day programmer activity is to filter some input file producing one or more output file. To some extent, it is the famouse REPL way of doing things: Read, Evaluate, Print and Loop. The basic idiom is to read, line by line, the input file and print the output file with some kind of separator and begin/trail string. A classic example could be having an SQL command as begin, comma separated values and a commit as end. What is the skeleton of this piece of code in Perl 5? As simple as:
 open my $input, "<", $ARGV[ 0 ] || die "\nError!\n$!\n";
 open my $output, ">", $output_file_name  || die "\nError!\n$!\n";
 while ( <$input> ){
     chomp;
     my @fields = map{ s/'//g;   s/^\"|\"$/'/g; s/'\s+/'/g; s/\s+'/'/g; $_  } split ',';
     say { $output } $begin_separator,
                     join( $separator, @fields ),
                     $end_separator;
 }

 close $output;
Simple enough pal? Open the $output and $input file handles, iterate one line at time (lazily) over the input file, do some kind of mangling (including chomping), split and re-map the fields and print one line on the output file. How to the same in Perl 6? This is a possible solution:
 my $ofh = $output.IO.open :w;
 for $input.IO.lines -> $line {
     my @fields = $line.split( ',' ).map: -> $_ is copy
                 { s:g/^\"||\"$/\'/; s:g/^\'\s+||\s\'+$/\'/; $_ };
     $ofh.say( $begin_separator, @fields.join( $separator ), $end_separator );
 }

$ofh.close;

A lot shorter, isn’t it? First of all the output file handle is opened in write mode, and while I could use spurt to print out a line on the file, that will close the file at each iteration, so I believe it is better to keep the handle around. The for loop performs the reading lazily, and the line is split and mapped. Please note that this time operators are read from left to right and not viceversa! In Perl 5 you would read map and split, while here you read split and map; in both cases the latter is the sequence of operations performed at run-time. Note also that $_ has to be marked as writable (thanks to Timo) because block and method arguments are read-only by default. Last, the usual print and join combo to put the line on the output file.

The article Perl5 -> Perl6: read and write to files has been posted by Luca Ferrari on September 20, 2017