Wednesday, January 6, 2010

Extracting the Tunes from a File

Just a quick post today. While reworking my test script for the DG accordion testing program, I decided it would be better if the script could accept an ABC file with multiple tunes in it. After about ten minutes of fiddling around, I came up with this:

my @matches = $*IN.slurp.comb(m/ <ABC::tune> /, :match);

Actually, that's a lie. I just came up with that a second ago, when I said to myself, "Wait a minute, maybe slurp works on $*IN?" Previously I was using lines and join to get the same effect.

The scary thing is, that's just the cleanest way I've been able to find to do it in Rakudo. In ideal Perl 6, I believe you could just say

my @matches = slurp.comb(m/ <ABC::tune> /, :match);

I believe in ideal Perl 6 that would be lazy, too, using the Cat class internally to get a lazy string.

Anyway, that gives you an array of Match objects, one for each ABC tune in the file. But there is one big gotcha with this formulation: if something happens to abort parsing the ABC::tune early (say it hits an ABC directive we haven't implemented yet), comb will merrily skip the rest of the tune without any warning. So this is probably a less than ideal approach in the long run. But my attempts to make a regex for the entire file have failed so far, and this works quite nicely on my sample data.

No comments:

Post a Comment