Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

Comment on

( #3333=superdoc: print w/ replies, xml ) Need Help??

I took my first baby steps with Pugs and Perl 6 during the past week and thought I'd share the experience.

Though I doubt it really counts as Exploratory Testing I decided to help test Pugs simply by converting an existing p5 program to p6.

The tsanta.pl test program (from my first Pugs node Replaying Santa Claus Golf Apocalypse with Pugs/Perl6) has now been rewritten as tsanta.p6 so that it runs successfully using Pugs, as shown below. You will need a more recent Pugs than 6.0.11 to run it -- suggest you simply install Subversion on your machine and enter:

svn checkout http://svn.openfoundry.org/pugs/
to get the latest Pugs release, then build it in the normal way. For full details on getting and building Pugs go to pugscode.org.

My other reason for attempting this is I feel we need more examples of real working Perl 6 code, both to help newbies learn the language and to provide valuable feedback to the Perl 6 design team. This is where I need some help from you. Though I can provide feedback on how easy Perl 6 is to learn and use for a newbie moving from Perl 5, a newbie cannot provide examples of good Perl 6 style. So, please feel free to suggest improvements to the code below (even if said improvements are not yet implemented in Pugs). It's nice to know the "right" way to do it.

The code below is constrained by the following assumptions about the current state of Pugs. If I am in error in any of these, please let us know.

  • In loops, next, last, redo are not yet implemented.
  • The length or similar function is not implemented. BTW, in p6 length is verboten, replaced by the more specific: bytes, codes, graphs, chars and elems.
  • Built-in vars like $., $! and $? are not yet implemented.
  • The chomp function is not yet implemented.
  • Here-docs are not yet implemented.
  • Backticks are not yet implemented.
  • Test for file existence with -f is not yet implemented.

So without further ado, here it is:

# tsanta.p6. Pugs version of tsanta.pl. use v6; sub length (Str $s) returns Int { +split("", $s) } sub golf_score (Str $script) returns Int { my $fh = open($script) or die("open '$script' failed"); my $golf = 0; my $dollar_dot = 0; # $. not implemented yet for =$fh -> $line { ++$dollar_dot; $golf += length($line) - 1 unless $dollar_dot==1 && $line.index("#!") == 0; } $fh.close(); return $golf; } sub print_golf_score (*@scr) { my $tot = 0; for @scr -> $s { $tot += golf_score($s) } print "You shot a round of $tot strokes.\n"; } sub build_file (Str $fname, Str $data) { my $fh = open('>'~$fname) or die("open '$fname' failed"); print($fh, $data) or die("print '$fname' failed"); $fh.close(); } sub slurp_file (Str $fname) returns Str { my $fh = open($fname) or die("open '$fname' failed"); my $s; for =$fh -> $line { $s ~= $line } $fh.close(); return $s; } sub check_one (Str $scr, Str $label, Str $data, Str $exp) { my $intmp = 'in.tmp'; my $outtmp = 'out.tmp'; build_file($intmp, $data); my $cmd = "pugs $scr $intmp >$outtmp"; print("$label : running: '$cmd'..."); # my $out = `$cmd`; # not implemented yet system($cmd); my $rc = 0; my $out = slurp_file($outtmp); print "done (rc=$rc).\n"; if ($out ne $exp) { $*ERR.print("Expected:\n$exp"); $*ERR.print("Got:\n$out"); die("Oops, you failed.\n"); } } # ----------------------------------------------------- my $file1 = "1st line "; my $file2 = "1st line 2nd line "; my $file3 = "1st line 2nd line 3rd line "; my $file4 = "1st line 2nd line 3rd line 4th line "; my $file12 = "1st line 2nd line 3rd line 4th line 5th line 6th line 7th line 8th line 9th line 10th line 11th line 12th line "; my $file21 = "1st line 2nd line 3rd line 4th line 5th line 6th line 7th line 8th line 9th line 10th line 11th line 12th line "; # ----------------------------------------------------- sub check_head (Str $scr) { my @tt = ( [ 'file1', $file1, "1st line\n" ], [ 'file2', $file2, "1st line\n2nd line\n" ], [ 'file3', $file3, "1st line\n2nd line\n3rd line\n" ], [ 'file12', $file12, "1st line\n2nd line\n3rd line\n4th line\n5th line\n"~ "6th line\n7th line\n8th line\n9th line\n10th line\n" ] ); for @tt -> $f0, $f1, $f2 { check_one($scr, $f0, $f1, $f2) } } sub check_tail (Str $scr) { my @tt = ( [ 'file1', $file1, "1st line\n" ], [ 'file2', $file2, "1st line\n2nd line\n" ], [ 'file3', $file3, "1st line\n2nd line\n3rd line\n" ], [ 'file12', $file12, "3rd line\n4th line\n5th line\n6th line\n7th line\n"~ "8th line\n9th line\n10th line\n11th line\n12th line\n" ], [ 'file21', $file21, "12th line\n\n\n\n\n\n\n\n\n\n" ] ); for @tt -> $f0, $f1, $f2 { check_one($scr, $f0, $f1, $f2) } } sub check_rev (Str $scr) { my @tt = ( [ 'file1', $file1, "1st line\n" ], [ 'file2', $file2, "2nd line\n1st line\n" ], [ 'file3', $file3, "3rd line\n2nd line\n1st line\n" ], [ 'file21', $file21, "\n\n\n\n\n\n\n\n\n12th line\n11th line\n10th line\n"~ "9th line\n8th line\n7th line\n6th line\n5th line\n"~ "4th line\n3rd line\n2nd line\n1st line\n" ] ); for @tt -> $f0, $f1, $f2 { check_one($scr, $f0, $f1, $f2) } } sub check_mid (Str $scr) { my @tt = ( [ 'file1', $file1, "1st line\n" ], [ 'file2', $file2, "1st line\n2nd line\n" ], [ 'file3', $file3, "2nd line\n" ], [ 'file4', $file4, "2nd line\n3rd line\n" ], [ 'file12', $file12, "6th line\n7th line\n" ], [ 'file21', $file21, "11th line\n" ] ); for @tt -> $f0, $f1, $f2 { check_one($scr, $f0, $f1, $f2) } } sub check_wc (Str $scr) { my @tt = ( [ 'file1', $file1, "0000000001\n" ], [ 'file2', $file2, "0000000002\n" ], [ 'file3', $file3, "0000000003\n" ], [ 'file4', $file4, "0000000004\n" ], [ 'file12', $file12, "0000000012\n" ], [ 'file21', $file21, "0000000021\n" ] ); for @tt -> $f0, $f1, $f2 { check_one($scr, $f0, $f1, $f2) } } # ----------------------------------------------------- my $head = 'head.p6'; my $tail = 'tail.p6'; my $rev = 'rev.p6'; my $mid = 'mid.p6'; my $wc = 'wc.p6'; # -f $head or die("error: file '$head' not found"); # -f $tail or die("error: file '$tail' not found"); # -f $rev or die("error: file '$rev' not found"); # -f $mid or die("error: file '$mid' not found"); # -f $wc or die("error: file '$wc' not found"); print_golf_score($head, $tail, $rev, $mid, $wc); check_head($head); check_tail($tail); check_rev($rev); check_mid($mid); check_wc($wc); print_golf_score($head, $tail, $rev, $mid, $wc); say("Hooray, you passed.");

Discussion

The code is remarkably similar to the Perl 5 version, indicating that many p5 scripts could be routinely converted to p6. I didn't try for any massive p6 improvements in converting this program -- mainly out of p6 ignorance.

I found writing this program a little frustrating mainly because of the lack of Perl 6 examples. The Synopses are important, but for learning a new language, my brain really needs lots of examples. Needless to say, if anyone knows of a good set of Perl 6 examples, please let me know.

I really like the new subs. Larry (or was it Damian) really hit the nail on the head when they said that p5 subs were, ironically, too orthogonal -- being implemented just with a special list @_ and without requiring any specialized language support at all! My first impression is that the new design of subs is a brilliant work of art and I salute the design team.

The new list stuff and functional programming support looks to be a huge improvement over p5 and I look forward to using it more in the future.

This little exercise uncovered one design bug and a couple of Pugs bugs also, so I feel it was worthwhile. If nothing else, it proves that real live working Perl 6 scripts can be written today. As a word of caution however, note that there are many p6 language features missing from Pugs today and working around them can be frustrating. On the other hand, the speed of the Pugs developers in implementing them is astonishing.

I knew there must be a better way than the slurp_file function above. As an example of the phenomenal enthusiasm and support by the Pugs developers, within an hour or so of posting a question about file slurping, autrijus has just now implemented the slurp primitive! Update: The latest version of tsanta.p6 (including replacing slurp_file above with the new slurp primitive) along with rg0now's excellent Santa golf solutions can be found under examples/golf in the Pugs distribution.

Finally, I would like to thank all the Perl 6 folks for being so helpful to a Perl 6 newbie and for not flaming me for my many silly questions. :-)


In reply to Pugs Baby Steps by eyepopslikeamosquito

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!
  • 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, 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, sup, table, tbody, td, tfoot, th, thead, tr, tt, u, ul, wbr
  • Outside of code tags, you may need to use entities for some characters:
            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.
  • Log In?
    Username:
    Password:

    What's my password?
    Create A New User
    Chatterbox?
    and the web crawler heard nothing...

    How do I use this? | Other CB clients
    Other Users?
    Others pondering the Monastery: (9)
    As of 2014-08-01 11:14 GMT
    Sections?
    Information?
    Find Nodes?
    Leftovers?
      Voting Booth?

      Who would be the most fun to work for?















      Results (7 votes), past polls