Day 9 – Data munging in Perl 6 vs Perl 5

One thing that Perl has traditionally been used for a lot, is small scripts which read some data (usually from a file), put it into a data structure, transform said data structure, and print some output based on it.

I believe that Perl 6, too, has the potential to appeal to people with such data wrangling needs (who may not necessarily be professional programmers, e.g. powerusers/sysadmins or students/scientists). Perl 6 does not share Perl 5’s selling-point of coming pre-installed on most *nix systems, but it entices with convenience features that allow script writers to focus more on what they’re trying to accomplish, and less on low-level technical details.

Let me showcase and compare an idiomatic Perl 5 solution and an idiomatic Perl 6 solution for the same simple data munging use-case (which might be a little contrived, but practical enough to be transferable to more complex problems), so you can form your own opinion:

Continue reading “Day 9 – Data munging in Perl 6 vs Perl 5”

Day 3 – File operations


Instead of opendir and friends, in Perl 6 there is a single dir subroutine, returning a list of the files in a specified directory, defaulting to the current directory. A piece of code speaks a thousand words (some result lines are line-wrapped for better readability):

    # in the Rakudo source directory
    > dir
    build parrot_install Makefile VERSION parrot docs 
    README dynext t src tools CREDITS LICENSE
    > dir 't'
    00-parrot 02-embed spec harness 01-sanity pmc

dir has also an optional named parameter test, used to grep the results

    > dir 'src/core', test => any(/^C/, /^P/)

Directories are created with mkdir, as in mkdir('foo')


The easiest way to read a file in Perl 6 is using slurp. slurp returns the contents of a file, as a String,

    > slurp 'VERSION'

The good, old way of using filehandles is of course still available

    > my $fh = open 'CREDITS'
    > $fh.getc # reads a single character
    > $fh.get # reads a single line
    > $fh.close; $fh = open 'new', :w # open for writing
    > $fh.print('foo')
    > $fh.say('bar')
    > $fh.close; say slurp('new')

File tests

Testing the existence and types of files is done with smartmatching (~~). Again, the code:

    > 'LICENSE'.IO ~~ :e # does the file exist?
    > 'LICENSE'.IO ~~ :d # is it a directory?
    > 'LICENSE'.IO ~~ :f # a file then?

Easy peasy.


When the standard features are not enough, modules come in handy. File::Find (available in the File::Tools package) traverses the directory tree looking for the files you need, and generates a lazy lists of the found ones. File::Find comes shipped with Rakudo Star, and can be easily installed with neutro if you have just a bare Rakudo.

Example usage? Sure. find(:dir<t/dir1>, :type<file>, :name(/foo/)) will generate a lazy list of files (and files only) in a directory named t/dir1 and with a name matching the regex /foo/. Notice how the elements of a list are not just plain strings: they’re objects which strinigify to the full path, but also provide accessors for the directory they’re in (dir) and the filename itself (name). For more info please refer to the documentation.

Useful idioms

Creating a new file
    open('new', :w).close
"Anonymous" filehandle
    given open('foo', :w) {
        .say('Hello, world!');