Tuesday, July 28, 2009

Testing in Perl 6

So, here's my first hesitant step to building Perl test code (specifically Perl 6 in this case, but I've never used any of the Test modules for Perl 5, either).

Simple and short, but with it I learned a significant limitation of my STEP extract script and turned up a Rakudobug. All in all, a most successful first foray into testing Perl code.

Now all I need to do is figure out the proper directory structure, and how to automatically build a makefile with a "test" target, and get the hacked version of Test.pm which properly handles planless testing.

Friday, July 24, 2009

Quick Bits

I have to report a complete FAIL on trying to install Padre + its Perl 6 extensions on my OS X. The Perl 6 stuff required me to install 5.10.0 from source, and even after I hand-hacked Mac::File so it would install, some other CPAN dependency that didn't install properly tripped me up, and I gave up on it. I may try again at a future date, but since I am unlikely to give up TextMate for Padre anyway, and my free time is actually negative at the moment, it seems a very low priority.

It also seems to have trashed my ability to run the STD.pm from Pugs -- looks like it may have installed its own non-compatible STD.pm? I haven't had time to investigate this yet.

On the bright side, Rakudo's "Chicago" release installed smoothly (and this time I had the good sense not to install it over my main Rakudo installation until I verified that it worked).

I am in awe of this script from pmichaud. Yes, that craziness works just fine in Chicago. I was very confused by the @deck .= pick(*); line, until I remembered that dot is now strictly used for member functions (or whatever the proper Perl 6 term is) -- thus it is really just shorthand for @deck = @deck.pick(*);. Once you know that pick picks random members from an array, then it's more-or-less clear that @deck.pick(*) returns a shuffled deck.

I'm working on trying to establish tests for my STEP extract script. I'm stuck on trying to figure out how to get the results back from an external command in Perl 6, but I'm sure I'll work it out sooner or later.

Tuesday, July 21, 2009

Perl 6 Taking Off

I read masak's post yesterday, and nodded my head in agreement, but didn't really think too much of it. Then last night I realized I could really use a Perl script to analyze the (C++) bug I was dealing with for work. And I thought about it a second, gulped, and started writing it in Perl 6.

Now, this wasn't the first work script I'd done in Perl 6. About six months ago I did a very handy little TextMate script in it. But writing that was a nightmare -- in fact, it turned out the feature that was the reason I wanted to use Perl 6 for the script wasn't actually implemented yet. I stuck with it, and with a lot of trial and error got a script that worked, but it wasn't fun or easy.

What a difference six months makes! My project was night was a classic simple Perl script, reading a text file, processing it a tad, and writing it back out in another format. The script took only marginally longer to write than it would have in Perl 5. Part of it was my much increased familiarity with Perl 6, no doubt. But I never ran into Perl 6 limitations at all! Everything I wanted to use was implemented and worked like a charm. There was one error message that could have been clearer, and that was it.

Big kudos are due the Rakudo team for making so much progress this year! Things are getting very exciting in the world of Perl 6...

Sunday, July 19, 2009

Perl 6 At Work

So, the Perl 6 script I talked about in my last two posts is now every bit as functional as the Perl 5 script it is descended from. And while I certainly recognize there is more to do to improve this script (both in better Perl 6 code and improved user interface), I can't begin to say how excited I am by this script. It really feels like a proper Perl 6 script at this point, and it strikes me as clearly superior to the Perl 5 version.

What do I like about it? The GetMatches sub is elegant in the way it takes a Regex and allows me to replace five lines of fairly hacky Perl 5 code with a single elegant line of Perl 6. And the given/when construct is a much cleaner way of handling command line arguments. (Admittedly this also gained over the Perl 5 version by eliminating dead code for ways I thought I would use the original script when I first wrote it.) Overall, the code has gotten significantly more element than the Perl 5 version, despite the fact that Perl 6 isn't finished yet.

Oh yes, what does this do? It extracts entities from a (Part 21 encoded) STEP file, including all the sub-entities that entity depends on. This is invaluable for debugging STEP support.

Improvements? In terms of Perl 6 usage, I'd love to get rid of the loop at the end that only does say. I guess I could use map for that, but just as I didn't like the thought of using map and ignoring its inputs, I don't like the thought of using map with side-effects.

I also wonder if the given statement is even needed. Can when be used with $_ from a for loop? And I look at the split loop and wonder if that could be more elegantly written in terms of my GetMatches function.

In terms of general code, I think there would be benefits from switching the entity references to straight numbers instead of numbers proceeded by a '#'. I'd certainly like some usage information. The code would be more reliable if it actually parsed the STEP data with some rules -- right now it's assuming that no one will ever use a semi-colon in a string in one of these files, and while that's never really caused me trouble in the past, it is a rash assumption. And I'd like to have support for tracing each entity's usage up to the top level to get its STEP context, which can be very important for imported. (Right now I do that sort of thing by hand after letting the script do the dirty work.)

Updated: Oh yes, for/when works every bit as well as given/when!

Updated again: One thing I'd really like to do is set up some tests for this -- if nothing else, it would make improving the script easier. Does anyone have hints on testing in Perl 6?

Wednesday, July 15, 2009

Getting STD.pm to work

In a comment to my last post, moritz suggested STD.pm would be a better check for the validity of my code as I ported it from Perl 5 to Perl 6. I duly set out to figure out how to do this -- and since I didn't find any hint of how to do it with a Google search, I'll document it here in hopes it helps someone else.

The legendary TimToady pointed me in the right direction. First, STD.pm and the scripts for using it live in the Pugs repository. I got http://svn.pugscode.org/pugs, though it may be possible to just get the src/perl6 directory tree, as that is the one we are interested in.

Once you have that src/perl6 directory, cd to it. You need to make to get it ready to use. Unfortunately, it is hardcoded to assume Perl 5.10 is available in /usr/local/bin/perl. If, like me, you only have 5.10 installed as a local user, you will need to go through the code and replace that path with the path to your Perl 5.10. (This is a great application for a quick Perl script.) You also need to have Moose and YAML::Syck installed. (I should thank moritz and PerlJam for helping me with getting this directory prepped to work.)

If you get that all set up and execute make and it doesn't return any errors, then you should have a working STD.pm! The tryfile command will try to parse your Perl 6 file carefully and provide sensible error messages.

Tuesday, July 14, 2009

Perl 6 Parsing Generously?

I just started a new little Perl 6 project by grabbing a little 99 line Perl 5 script, sticking use v6; at the top, and running it through Rakduo. Much to my surprise, a lot fewer things were complained about than I expected. (So far, I'm only about one-third through the first stage of the port.)

It did complain about my $in_file = shift; to store the next value from @ARGV/@*ARGS, about foreach $arg (@*ARGS), and about using dot from string concatenation. But it did not complain about if ($arg =~ /^\-sd/), for ($i = $1; $i <= $2; $i++), or open IN_FILE, $in_file or die. I wouldn't have expected any of those to get through the parser? (I'm assuming they'll fail when the code finally is ported enough to reach proper execution.)

I'm also trying to figure out how to automatically test this script. I guess I can easily enough throw a few files at it and check to make sure the results are correct. Does it make sense to try to unit test something this small? (As it is, the Perl 5 version has no subs at all!) And what is the accepted way of doing such testing in Perl 6?

Tuesday, July 7, 2009

Dice Game Again

After seeing Daniel Ruoso's lovely version, I decided to take another crack at the the dice game:

Notice that once the payback subroutine is defined, the all the calculations are done with a simple one-liner, followed by a single say to print the results, and then wrapped with MAIN to produce a command-line interface. Wee!

Alas, I believe this would be the slowest version yet but for the fact I replaced * with $_ in the given / when statement.