I wanted an overview of S29. More exactly, I wanted a list of functions. The table of contents in S29 itself didn't cut it, because it stopped short at the level of classes, and left out the functions. That's when I decided to extract the relevant information using a script of my own. I mean, how hard can it be?
Turns out it was easy.
Duh, right? We have Perl this is what Perl does: extract and report. (Practically.) Because it turned out to be a three-minute one-liner in Perl 5, I decided to turn it into a Perl 5 script file, and then into a Perl 6 script file.
The results were a bit interesting, and I thought I'd share.
First, a description of the problem:
=head2 $class
, and the functions by =item $function
.=over 4
and =back
stuff that we don't care about.=head1 Function Packages
.Here's my one-line solution:
$ perl -e '$_ = <> until /Function Packages/; while (<>) { if (/^=(\S+) (.*)/) { next if $1 eq "over"; print " " x 4 if $1 eq "item"; print $2, "\n" } }' S29-functions.pod
If you're interested in the output it produces, try running it after cd
-ing into the directory docs/Perl6/Spec
in the Pugs repo.
Here's the corresponding turned-into-a-file script (still Perl 5):
use strict; open my $S29, '<', 'S29-Functions.pod' or die $!; until (<$S29> =~ /Function Packages/) {} while (my $line = <$S29>) { if ($line =~ / ^ = (\S+) ' ' (.*) /x) { next if $1 eq 'over'; if ($1 eq 'item') { print ' ' x 4; } print $2, "\n" } }
Things are a bit more indented, a bit more Best Practices, but no revolutionary changes. It's the same script.
Now, take a look at the Perl 6 script:
use v6; my $S29 = open('S29-Functions.pod', :r) or die $!; repeat {} until =$S29 ~~ /'Function Packages'/; for =$S29 -> $line { if $line ~~ / ^ '=' (\S+) ' ' (.*) / { next if $0 eq 'over'; if $0 eq 'item' { print ' ' x 4; } say $1; } }
Noteworthy differences:
use strict
is implicit in use v6
.open
syntax is different. I stumbled on this, and had to go look in a spectest file to remind myself.repeat {} until $cond
unstead of {} until $cond
, because I think it looks better. The old way still works, too.while
loop is a for
loop. Beware, young Perl 6 hatchlings! In Perl 6 land, we for
loop over our files and other stream-like things. That way, we don't have to do an assignment (explicit as in my Perl 5 script, or implicit with $_
). Things are more lazy in Perl 6, so the for
loop doesn't cause the file to be slurped or anything like that. (For what it's worth, I forgot to use a for
loop and used a while
loop instead, with segfaults as a result. That was an indication that I was doing something wrong.)for
and if
./x
.$1, $2, ...
match variables are pushed down one step. For great justice. And consistency.say
like I did (i.e. to finish off a line that has been printed in several stages), but it seemed nice, so I decided to give it a try. So far, I like it.There you have it. A Perl one-liner grows up.
Re:a safer one-liner
masak on 2009-01-05T12:00:58
Great work, masak. I started using that in Padre::Plugin::Perl6 to index Perl6 functions.
Happy to hear that.
A more safe one-liner that works even on win32 platforms.
perl -e "$_ = <> until
/Function Packages/; while (<>) { if (/^=(\S+) (.*)/) { next if $1 eq q{over}; print q{ } x 4 if $1 eq q{item}; print qq{$2\n} } }" S29-functions.pod That version may work on win32 platforms, but it doesn't in bash, which does variable interpolation of double-quoted strings. Single quotes work.
Thanks for the tip about
q{}
andqq{}
, though! I really should remember to use those more in one-liners, where single quotes are essentially hijacked by the-e
string.Re:a safer one-liner
azawawi on 2009-01-05T12:53:23
Cool. Thanks for the bash tip.
Please take a look at the updated code for parsing S29 for documentation and selecting the correct one. I think S29 needs to be updated in some =item-s to be more consistent.
http://padre.perlide.org/browser/trunk/Padre-Plugin-Perl6/lib/Pad re/Plugin/Perl6.pm.