I have posted a draft tutorial in my scratchpad here below (per Arunbear's suggestion) and am looking for constructive criticism. Thanks.

UPDATE 1: Added three subheadings including an informal list of Perl 6's desirable features.

UPDATE 2: Added link to rosettacode in the "Some Longer Comments" section below.

UPDATE 3: After some rework (perltidy, perlcritic) in the Perl 5 code, modified the Perl 6 code accordingly, then made additional improvements to the Perl 6 code to be more Perl6ish.

=== BEGIN TUTORIAL ===

Introduction

Perl 6 is almost upon us, and it promises to cure many of the shortcomings of Perl 5. For all the official information, check out its web site at <http://perl6.org>. I use the instructions here <http://rakudo.org/how-to-get-rakudo/> for a Linux source installation with the rakudobrew script.

I asked for users opinions of Perl 6's "killer" features on the Perl 6 users list and following are some of the responses:

Some longer comments:

Purpose

This tutorial aims to show how my typical modest Perl 5 scripts translate into Perl 6. As the current Perl 6 documentation is not yet complete, my beginning Perl 6 efforts have resulted in putting together a simple model for a typical task for me. It was completed somewhat by trial and error along with much help from the Perl 6 mailing list.

The Code

A typical script of mine does something like the following:

The following table is a side-by-side comparison of the two example programs (both of which work for me; please report any errors you may find). There are some comments to indicate differences in Perl 5 versus Perl 6, but many are not documented explicitly. In many cases of my Perl 6 usage, as in Perl 5, TIMTOWTDI, so I'm sure both programs can be improved.

Below the programs is the input data file used by each program. Run each program like this to compare results (assuming you have done chmod +x filename for each file):

$ ./tutorial-p5.pl -g -d >& p5.txt $ ./tutorial-p6.pl -g -d .& p6.txt
Perl 5Perl 6
#!/usr/bin/env perl # file: tutorial-p5.pl # PRELIMS ======================== use v5.10; # features 'say' and 'state' use strict; use warnings; use File::Basename; # p6: no such module yet use Data::Dumper; my $default_infile = 'tutorial-data.txt'; my $prog = basename $0; my $debug = 0; my $infile = 0; my $usage = "$prog: --go | --infile=<data file name>"; $usage .= ' | --help | ? [--debug[=N]]'; # ARG/OPTION HANDLING ======================== if (!@ARGV) { say $usage . "\n"; exit; } foreach my $arg (@ARGV) { my $oarg = $arg; # save original for error handling my $val = undef; my $idx = index $arg, q{=}; if ($idx >= 0) { $val = substr $arg, $idx+1; $arg = substr $arg, 0, $idx; } if ($arg eq '-g' || $arg eq '--go') { $infile = $default_infile; } elsif ($arg eq '-i' || $arg eq '--infile') { $infile = $val; } elsif ($arg eq '-d' || $arg eq '--debug') { $debug = defined $val ? $val : 1; } elsif ($arg eq '-h' || $arg eq '--help' || $arg eq q{?}) { long_help(); } else { die "FATAL: Unknown argument '$oarg'.\n"; } } # MAIN PROGRAM ======================== die "FATAL: No such file '$infile'.\n" if (! -e $infile); my %user; my @keywords = qw(last first job); my %keywords; @keywords{@keywords} = (); parse_data_file($infile, \%user, $debug); if ($debug) { say 'DEBUG: Dumping user hash after loading:'; print Dumper(\%user); } else { say 'Normal end.'; } #### SUBROUTINES ======================== sub parse_data_file { my $fname = shift @_; my $href = shift @_; my $debug = shift @_ || 0; say "Parsing input file '$fname'..."; open my $fp, '<', $fname or die "$fname: $!"; my $uid = undef; my $linenum = 0; while (defined(my $line = <$fp>)) { ++$linenum; my $err = 0; # remove comments my $idx = index $line, q{#}; if ($idx >= 0) { $line = substr $line, 0, $idx; } # skip blank lines next if $line !~ /\S/xms; # every valid line must have a colon (':') # following a key word $idx = index $line, q{:}; if ($idx >= 0) { # ensure the key is lower case my $k = lc substr $line, 0, $idx; # trim ws on both ends $k =~ s{\A \s* | \s* \z}{}gxms; my $val = substr $line, $idx+1; # also needs trimming $val =~ s{\A \s* | \s* \z}{}gxms; # User attributes if ($k eq 'user') { $uid = $val; die 'FATAL: $uid not defined.' if !defined $uid; if ($uid =~ /\D/xms) { say 'ERROR: User ID not an integer.'; ++$err; } elsif ($uid <= 0) { say 'ERROR: User ID not an integer > 0.'; ++$err; } elsif (exists $href->{$uid}) { say 'ERROR: User ID is not unique.'; ++$err; } next; } # for the following keys, an exception will be # thrown if $uid is not defined if (!defined $uid) { say 'ERROR: User ID is not defined for this user.'; ++$err; } elsif ($k eq 'hobbies') { $href->{$uid}{hobbies} = []; my @h = split q{,}, $val; foreach my $h (@h) { # trim ws on both ends $h =~ s{\A \s* | \s* \z}{}gxms; push @{$href->{$uid}{hobbies}}, $h; } } elsif (exists $keywords{$k}) { $href->{$uid}{$k} = $val; } else { chomp $line; say 'ERROR: Unknown line format:'; say " '$line'"; ++$err; } } else { say 'ERROR: Unknown line format.'; ++$err; } if ($debug) { chomp $line; say STDERR "DEBUG: line = '$line'"; } if ($err) { chomp $line; say "FATAL error in file '$fname' at line $linenum:"; say " '$line'"; exit; } } } # parse_data_file sub long_help { say <<"HERE"; Usage (one of the following three): $prog --go (or '-g') $prog --infile=<data file name> (or '-i=') $prog --help (or '-h' or '?') The '--go' option uses the default input file: $default_infile Any of the first two options can use the '-d' (or '--debug') flag for debugging. A debug number may be provided with '-d=N' (or '--debug=N'). HERE exit; } # long_help # EOF ========================
#!/usr/bin/env perl6 # file: tutorial-p6.pl # PRELIMS ======================== use v6.0; # not required, but good practice for # maintenance # 'strict' and 'warnings' are the default # Note: Using perl6 -v => # '2015.07.1-66-g0dcbba7 built on MoarVM version 2015.07-8-gb8fdeae' use Data::Dump; my $default_infile = 'tutorial-data.txt'; my $prog = basename($*PROGRAM); my $debug = 0; my $infile = 0; my $usage = "$prog: --go | --infile=<data file name>"; $usage ~= ' | --help | ? [--debug[=N]]'; # '~=' instead of '.=' # ARG/OPTION HANDLING ======================== # See [http://design.perl6.org/S06.html] # for built-in methods similar to Getopts::Long if !@*ARGS.elems { say $usage ~ "\n"; # '~' instead of '.' exit; } for @*ARGS -> $arg is copy { # 'is copy' allows modifying locally my $oarg = $arg; # save original for error handling my $val = Any; # 'Any' instead of 'undef' my $idx = index $arg, '='; if $idx.defined { # index is defined if an index is found $val = substr $arg, $idx+1; # use substr function $arg = substr $arg, 0, $idx; } if ($arg eq '-g' || $arg eq '--go') { $infile = $default_infile; } elsif ($arg eq '-i' || $arg eq '--infile') { $infile = $val; } elsif ($arg eq '-d' || $arg eq '--debug') { $debug = defined $val ? $val : 1; } elsif ($arg eq '-h' || $arg eq '--help' || $arg eq q{?}) { long_help(); } else { die "FATAL: Unknown argument '$oarg'.\n"; } } # MAIN PROGRAM ======================== die "FATAL: No such file '$infile'.\n" if $infile.IO !~~ :f; my %user; my @keywords = <last first job>; my %keywords; %keywords{@keywords} = (); parse_data_file($infile, %user, $debug); if $debug { say "DEBUG: Dumping user hash after loading:"; say Dump(%user); } else { say 'Normal end.'; } #### SUBROUTINES ======================== sub parse_data_file(Str $fname, # declare args #Any $href, %href, Int $debug = 0) { say "Parsing input file '$fname'..."; my $uid = Any; # p6 doesn't use 'undef' my $linenum = 0; for $fname.IO.lines -> $line is copy { ++$linenum; my $err = 0; # remove comments my $idx = index $line, '#', 0; if defined $idx { $line = $line.substr(0, $idx); } # skip blank lines next if $line !~~ /\S/; # '~~' and '!~~' for matching # every valid line must have a colon (':') # following a key word $idx = $line.index(':'); if $idx.defined { # ensure the key is lower case my $k = $line.substr(0, $idx).lc; # trim ws on both ends $k = $k.trim; # string object method my $val = $line.substr($idx+1); # use object method # also needs trimming $val = $val.trim; # User attributes if $k eq 'user' { $uid = $val; die "FATAL: \$uid not defined." if !$uid.defined; if $uid ~~ /\D/ { say "ERROR: User ID not an integer."; ++$err; } elsif $uid <= 0 { say "ERROR: User ID not an integer > 0."; ++$err; } elsif %href{$uid}:exists { # 'exists' adverb say "ERROR: User ID is not unique."; ++$err; } next; } # for the following keys, an exception will be # thrown if $uid is not defined if !$uid.defined { say "ERROR: User ID is not defined for this user."; ++$err; } elsif $k eq 'hobbies' { # literal string keys must be quoted %href{$uid}<<hobbies>> = []; my @h = split ',', $val; for @h -> $h is rw { # trim ws on both ends $h .= trim; # literal string keys must be quoted # use '@()' instead of '@{} push @(%href{$uid}<hobbies>), $h; } } elsif %keywords{$k}:exists { %href{$uid}{$k} = $val; } else { $line .= chomp; say "ERROR: Unknown line format, \$k = '$k'."; say " '$line'"; ++$err; } } else { say 'ERROR: Unknown line format (no key).'; ++$err; } if $debug { $line .= chomp; say "DEBUG: line = '$line'"; } if $err { $line .= chomp; say "FATAL error in file '$fname' at line $linenum:"; say " '$line'"; exit; } } } # parse_data_file sub long_help { # note indent is taken from position of ending token say qq:to/HERE/; Usage (one of the following three): $prog --go (or '-g') $prog --infile=<data file name> (or '-i=') $prog --help (or '-h' or '?') The '--go' option uses the default input file: $default_infile Any of the first two options can use the '-d' (or '--debug') flag for debugging. A debug number may be provided with '-d=N' (or '--debug=N'). HERE exit; } # long_help sub basename(IO::Path $fname) { # no File::Basename module in p6 yet my $idx = rindex $fname, '/'; if $idx { return $fname.substr($idx+1); # use substr method } return $fname; } # basename # EOF ========================

Following is the input data file used in the programs above:

# file: tutorial-data.txt # a data file of users and their attributes # note all valid lines are in format "key: value..." user: 1234 # unique ID (an integer > zero) last: Brown first: Sam job: gunsmith # hobbies may be a comma-separated list hobbies: hunting, Perl Monging user: 2316 last: Doe first: Jane job: financial analyst hobbies: Python open source, bowling

In reply to RFC: (DRAFT Tutorial) A Gentle Introduction to Perl 6 by u65

Title:
Use:  <p> text here (a paragraph) </p>
and:  <code> code here </code>
to format your post, it's "PerlMonks-approved HTML":



  • Posts are HTML formatted. Put <p> </p> tags around your paragraphs. Put <code> </code> tags around your code and data!
  • Titles consisting of a single word are discouraged, and in most cases are disallowed outright.
  • Read Where should I post X? if you're not absolutely sure you're posting in the right place.
  • Please read these before you post! —
  • Posts may use any of the Perl Monks Approved HTML tags:
    a, abbr, b, big, blockquote, br, caption, center, col, colgroup, dd, del, details, div, dl, dt, em, font, h1, h2, h3, h4, h5, h6, hr, i, ins, li, ol, p, pre, readmore, small, span, spoiler, strike, strong, sub, summary, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • You may need to use entities for some characters, as follows. (Exception: Within code tags, you can put the characters literally.)
            For:     Use:
    & &amp;
    < &lt;
    > &gt;
    [ &#91;
    ] &#93;
  • Link using PerlMonks shortcuts! What shortcuts can I use for linking?
  • See Writeup Formatting Tips and other pages linked from there for more info.