Thursday, June 25, 2009

Perl 6 Working Again on OS X

As I believe I mentioned in a previous post, upgrading Rakudo to Pittsburgh broke it for me on my MacBook Pro and my 64-bit Linux box. It failed running test t/01-sanity/07-isa.t. This morning I got the test running again by switching to the parrot subdirectory, doing svn update, and running make. Then I switched back to the Rakudo directory and rebuilt it. Now make test runs fine. Yay!

So here's my first stab at the squares program in Perl 6. It's a lot more compact than the Perl 5 version, but I feel dirty using map solely for a side-effect. Surely there must be a better way to do it?

Update: Thanks to moritz_ and Tene on #perl6, I now have a much more Perl 6ish version:

Wednesday, June 24, 2009

Ovid on TDD

Hacker News just gave me a pointer to a nice post of Ovid's on test-driven development. "Many people realize that exploratory programming and TDD don't always play well together." That's a lot of my issue with it. More often than not, when I program I'm looking for the right approach to interfacing with someone else's code or file format. It's very hard to create meaningful unit tests ahead of time in those circumstances, because you don't know what the right answer is ahead of time.

Tuesday, June 23, 2009

Detecting Squares Cheaply

So, moritz_ on #Perl6 asked about detecting squares cheaply, ie without just calling sqrt. A quick Google search led me to Detecting Squares, which has a nice discussion on quick filters you can use. moritz_ got me thinking about looking at the same problem in more computer-oriented terms. It's quickest to compute if you can just look at the least significant byte of the number instead of computing mod 100 (as the above page suggests). So here's a quick and dirty Perl 5 program to find the magic numbers:

That determines there are 44 numbers that repeat if you look at the first hundred thousand squares mod 256. And in fact, you don't need to look at nearly that number. Say your number N = 256n + m, where m is less than 256. Then N squared is 65536n^2 + 512nm + m^2, which is congruent to m^2 mod 256. That is to say, the least significant byte of N is the only byte which contributes to the least significant byte of N squared.

This means that given a random number, you can determine 212 out of 256 times (about 82%) that the number is not a square by doing a simple table lookup on the last byte of the number.

(I think a really pretty little Perl 6 program could also be used to demonstrate it, but I'm not going to try while my Perl 6 build is broken.)

Monday, June 22, 2009

CPAN Good, Bad, and Ugly

Watching this awesome video Introduction to Catalyst, I was inspired to try it myself.

And that's when the trouble started. It's now three hours later, and I'm still trying to get Catalyst down from CPAN. And I have no confidence I will have a properly working version when it finally does finish installing.

My first attempt to get Catalyst::Runtime and Catalyst::Devel was on my Linux server's default 5.8.x Perl. It ran for maybe fifteen minutes, and then complained that there was something wrong with my distribution's Perl, and I should complain to the distribution packagers.

You know, that might seem like a great way to bring about long term change, but it doesn't seem like the most productive use of my time this morning. So I decided what the heck, let's install 5.10 just to my personal account -- the perfect way to experiment with it without risking blowing up my nice, happy server. (Besides, I've wanted access to 5.10 ever since I started reading the various Perl blogs. Too many goodies to ignore.)

Now this is another positive point -- 5.10 installation was perfectly smooth, even to a non-standard directory. Sweet!

Installing Catalyst took a long time, and came up with the following error:

# You are using perl 5.10.0 with the "Unknown error" bug. This can make #
# developing Catalyst applications much more painful, as it will come #
# up with no details every time you have a syntax error in a Controller.#
# #
# For more information see: #
# #
# * #
# #
# It is highly recommended that you use a different version of perl or #
# compile a patched version for Catalyst development. #

So the link there gives the number of the commit to the Perl source that fixes the bug. But it doesn't provide any obvious way of easily getting that patch. And Perl is in git now, right? I don't see any obvious way of associating that number to a git commit to extract the patch.

So now it's the next day from when I did all that. I have Catalyst installed, and it performed the basic cool step in that tutorial admirably. But I've also got this lingering unfixed bug hanging over my head, too.

And that's the mixed bag of Perl at the moment. On the one hand we have these cool things like Catalyst and Perl 5.10, and that great screencast promoting Catalyst. And on the other hand we have this funky cruft that turns what could be pure awesome into something messy and a bit embarrassing.

I don't have any idea who to blame; I suspect there is a little bit of blame spread out over a large range of not terribly guilty parties. (Including myself -- I'm sure given time I could track down how to get the patch, and put that answer here and/or patch Catalyst to put the answer there.)

But that's my experience with it. Hopefully things will go more smoothly now that Catalyst is installed...

Saturday, June 20, 2009

More respectable

Here's a somewhat more respectable version of the "change files with backup" script. It uses File::Copy instead of the unportable system call in the old version, actually checks the copy call for success, and has use strict in place, too. Still not rocket science, but at least it's a bit less dodgy and more portable.

I'm considering replacing the first loop with a map, and maybe playing around a bit more with it. But first I need to tackle some C++ for work.

P.S. Two other things worth pointing out. First, this is exactly the sort of small problem Perl excels at tackling -- quick scripts that make a hard job simple. (That's not to say Perl can't tackle big projects, too!) And second, with the proper switches one can more or less duplicate this program's actions straight from the command line.

P.P.S. The file has been updated to incorporate the map idea I had, and autarch's three-arg open suggestion from the comments. Plus I cleaned up the regular expression I used to get the file extension (in retrospect, the old one was dire) and switched from || to or throughout.

May try perlcritic next.

Adventures in IRC

Yesterday I spent time in #perl6 for the first time. Basically, I tried updating to Rakudo's Pittsburgh release and it failed for me. So I poked my head into #perl6 to see what to do about it. I gave it "" as my ID, and it thoughtfully translated it to "last" for me, so I suppose I'll probably try "SF" next time.

Anyway, no solution for the bug, so moritz walked me through the process of submitting a Perl 6 bug report. That done, I hung around on the channel all day, just to see what it was like. (Crazy to see Larry Wall checking a bunch of stuff into the repository while I was watching.)

After dinner, someone came around asking for help with a simple Perl 5 regex. No one else seemed to be using the channel for anything, so I went ahead and helped him there. And naturally, in the process, help me with a regex turned into help me with two regexes and then the entire program to use them. In the process of trying to help him quickly, I dug up and posted my old script for running substitutions on a bunch of files.

About thirty minutes later I started regretting having done that. That code is simple, but pretty awful for how simple it is. It's not properly error checked, I obviously didn't use strict, and it is Windows-specific as written. (BTW, if the code at the above link looks okay, that means I've updated it already. You should check out the earlier revisions for the full badness.)

Anyway, I've decided as penance for posting bad code to the net and Perl 5 on the Perl 6 channel at that, I'm going to clean it up in Perl 5 and then take a stab at translating it to Perl 6 this weekend. (The latter will probably be easier if I can get Perl 6 working again!) It should be a pleasant distraction from the ugly C++ API overhaul I need to do for work.

Wednesday, June 17, 2009

Perl 6 Array Notation

Gabor Szabo uses the following example as his first when talking about arrays in Perl 6:

Now, as I understand it, .perl is supposed to generate the Perl 6 code to create the array, right? So why is it parentheses when he defines the array's contents, but brackets when .perl stringifies it? Are they interchangeable, or is there some special meaning for each?

I tried looking up the answer in S02. As often happens, I learned a lot of interesting points this way, but completely failed to answer my question.

Sunday, June 14, 2009

Adventures with WD MyBook as a Linux Server

I've been looking for a small Linux server with a large disk that I could put at my in-laws' house to use as off-site backup for my data. Thursday I read about a hack to use the Western Digital MyBook World Edition (with Ethernet) as a Linux server and went right out and bought one.

My first surprise came when I discovered the hack was no longer necessary on the latest version of the disk -- you could simply turn on SSH access from their configuration software! The downside for this is most of the online advice for using the MyBook as a Linux server assumes you have no older version, and no longer applies to the new code. So there has been lots of feeling my way around blind.

The default setup for a normal user share (instead of root) is a bit weird -- though it creates a home directory for you, it's not the user's actual home directory. Hand-editing the passwd file fixed this. Plus chown-ing the directory so I owned it, and chmod-ing it to 744. Then it was easy enough to add a .ssh directory with an authorized_keys2 file.

Unfortunately, my first attempt to lockdown the machine so you can't use plain passwords to SSH locked up the SSH quite thoroughly, and I could no longer log in. After some frustrating poking at it, I reset the machine to factory defaults so that I could get back into it. (It's possible I should have tried rebooting the machine at this point -- see below.)

And that's where things get really weird. Because it did delete my user id and reset things so I could log in again. But it didn't actually restore the machine to the way it shipped -- the root directory still had the .ssh and authorized keys I had added to it, and the etc directory still had my modified ssh_config file. The authorized keys was definitely working, but the ssh_config file appeared to be ignored -- at least, it let me use a password to log into my user account (once it was recreated). So weirdly enough, it was sort of magically doing exactly what I needed to get it going again, without undoing all the work I had done.

This time I think I'll follow the advice to turn on telnet as an alternative to SSH, at least until I've got the SSH configuration worked out just the way I'd like it...

Saturday, June 13, 2009

Mandelbrot in Perl 6

I decided to take a stab at translating from The Computer Language Benchmarks Game to Perl 6. I got rid of the threading, and because I was unable to get pack working (not there or just 5 AM programming issues?), I switched it from a P4 binary file to a P1 ASCII file. The resulting code runs in 3 minutes and 20 seconds, where the unthreaded version of the original runs in 0.2 seconds, so there is a lot of room for improvement here.

I'll probably also take a stab at revamping the dot function to use the Complex type, assuming it actually is implemented, and maybe making lines feel more Perl 6ish.

Tuesday, June 9, 2009

valgrind now on OS X!

One of my very favorite development tools, valgrind, is now available for the Mac. For years I have done my main development on Windows (more recently, OS X), then transferred my code over to a Linux box when I needed to run valgrind. Now that it supports OS X I will only need to switch over to Linux when I'm dealing with a very large process. (The big Linux box is a quad core machine with 8 GB RAM, the MacBook Pro cannot keep up with that.)

Automagically Generating a Guide

fREW suggests some clever automatic ways to generate a guide to CPAN. Certainly if it can be done well, that is preferable to the inevitable bickering that would result from a non-objective guide!

I did have one additional notion that might help, thought I can't decide if it is crazy or not. What about some sort of opt-in anonymous module usage monitoring, ala's scrobbling? It could help figure out which modules are in common use -- imagine doing a CPAN search sorted by usage. It could be another handy stat feeding into an automatically generated guide. It would also allow easy searches for orphaned modules that are in heavy use.

Obviously there are privacy objections, potential speed issues, worries about gaming the system, etc...

Saturday, June 6, 2009

Guide to CPAN Needed

I'm all in favor of chromatic's suggestion to dump most of the core Perl modules. But I think he left out what might be the most important (and most controversial?) part of such a plan: providing a proper guide to CPAN.

In a previous post I complained about the difficulty of figuring out what MP3 tagging module to use. CPAN is great at providing alternatives, but not terribly good at providing a way to evaluate the pros and cons of those alternatives.

Now, with something like MP3 tagging that is just an inconvenience. But if it happened to core modules, it would be a disaster for Perl. The best thing about the core modules is you know they are a standard. If you want to do, say, standard file handling, you us IO::File, simply because it is there. But if it's not there, and you're a beginning searching CPAN, you'll be confronted with dozens of modules that sound like they might do the right thing. It's an utter nightmare for the poor beginner who just wants to get his twenty line script running.

It seems to me the answer is a guide to CPAN, something that points out what you should probably use and what you should avoid at all costs. Maybe it should be a web page, or a wiki, or just a standard module package that everyone should install. But something is needed, and it will have to be opinionated to be useful.

PS It is especially needed because you've got to think people will start re-evaluating those basic modules in light of the past ten years' changes to Perl (and the even greater ones coming chromatic envisions). Moose::IO::File anyone?

Thursday, June 4, 2009

Perl to the Rescue

So here's a simple example of the sort of small Perl script I routinely cobble together for work. In this case I needed to run a quick external program repeatedly on a series of files and extract the parameters used inside. The files were named with whether or not they were correct, and this code uses that to build a table which sorts the files and summarizes the parameters.

There are a few ways this script is atypical for me. The brainwashing has worked -- for the first time I can remember, I actually started a script with use strict. I don't think it saved me this time, but it was simple enough to obey its strictures.

This is the first time I've used the DirHandle module. Combined with grep, it proved an elegant way to get the filenames to work on.

And actually, the use of grep to filter lists is a fairly new technique, which I think I picked up in my Perl 6 experiments.

By the way, once the full table was generated, I had the bug's cause pinned down in about twenty seconds.

Monday, June 1, 2009

Lost in the CPAN

A Foolish Manifesto has an interesting post on renaming MP3 files. It's a simple little script, the likes of which I have written several times over the years. Yet I don't recognize any of the modules he is using.

I actually noticed this the last time I tried to write one of these scripts. CPAN has a number of different MP3 tag modules, all in various states of disarray. I know I have used different modules over the years as I coded quick MP3 tag hacks, but the time between these hacks is so long that every time I feel like I'm starting fresh -- with no idea where in the maze to start.

Now fREW reveals a new one I never noticed before, Music::Tag. (Presumably it handles more than just MP3s.) I see it is at version 0.33, and hasn't had a release in over a year, which leads me to suspect it is yet another orphaned tagging module.

Is it possible for the vastness of the CPAN to actually become a disadvantage? It seems to me that if there were only one tag module instead of 5+, that one would be better supported. And it would be a lot easier for a potential user to figure out what to use.