Author Archives: Chris

SCALE 11x

Over the weekend, I attended the eleventh annual Southern California Linux Expo (SCALE 11x) at the Hilton Los Angeles Airport. I’ve been to this event a handful of times and always thoroughly enjoy myself. The hard-working folks that volunteer to run this conference outdo themselves every year.

The Expo Floor

I didn’t spend much time on the expo floor, walking through it only a couple of times. I’m not currently looking for anything to use at work, I’m not on the job market, and nothing captured my interest.

In retrospect, one thing I wish I had done was Rackspace’s breakfix challenge, which they were using as a recruitment tool. The idea behind it is that you are seated at a computer on which things are broken and are given some fixed amount of time to accomplish a number of tasks to bring the computer back to health. On Monday, my boss came into my office to enlist my help tracking down a strange bug in the way some shell initialization files were being sourced. This had been bugging (heh) them for a week and has caused some stoppage of work. After making his head spin for a few minutes, I found the problem and hacked up a workaround. So yeah, I kind of wish I’d tried my hand at the challenge.

The Sessions

I won’t attempt lengthy descriptions of the sessions I attended (there are probably dozens online already, and I think many of the sessions were recorded and will be put online). Instead, I’ll try to comment on what, if anything, I took away from each session.

Saturday Keynote: The Secure Boot Journey (Matthew Garrett)

The staff at SCALE did a great job in lining up this keynote. It was entertaining and educational. The real fear of not being able to boot Linux on commodity hardware was palpable, and I was left impressed by the efforts put forth to ensure user freedom in that respect.

I also learned that, if drinking doesn’t solve the problem, try drinking some more. If that doesn’t work, wait for the hangover to wear off, then cause trouble. Also, standards are wonderful, if you’re on the right side of them. Microsoft used the UEFI standard to defend their position on Windows 8 and secure boot. The speaker made the point that 5.56x45mm NATO is a standard, but few people on the receiving end are appropriately happy for that.

Scaling systems configuration at Facebook (Phil Dibowitz)

This session convinced me that Chef is very cool, but also very scary. It reminded me of the adage, stated by Doug Gwyn, “Unix was not designed to stop its users from doing stupid things, as that would also stop them from doing clever things.”

As a programmer, I like the idea that a configuration management system is simply a set of objects on top of a full programming language. If it doesn’t do exactly what I want, I can hack it to do so, as was demonstrated in the session. However, the thought of then handing the ability over to junior (or even senior) system administrators leaves me with no small amount of fright.

Free to be a kid (Keila Banks)

I love that SCALE had an entire track dedicated to the youth in our community. A lot of us have had, or will have, children. This is a great way of introducing younger audiences to our hobbies and fostering that curiosity and creativeness that got us started. In fact, one of the friends I attended SCALE with brought his son, who attended the two-day Linux Beginner’s Training Class.

This session wonderfully highlighted that curiosity and creativeness. Presented by the 11-year-old daughter of one of the SCALE organizers, we learned about all of the fun and useful things she does with Open Source software. From playing games to writing blogs and publishing her class’s weekly newsletter. She is exactly what I hope my daughters become.

Checkpoint, Restore, Live Migration and beyond (Kirill Kolyshkin)

I found this session interesting from an academic standpoint. It’s cool that this is being done at the kernel level, but I’m not sure how useful it is to me. The overhead of running KVM is less and less noticeable every year, and it already provides a lot of (if not all of) the capabilities already. There was some discussion about working with NFS mounts, which did pique my curiosity, but that came up during questions after the presentation. By then my eyes had already glazed over.

Practical Application Troubleshooting using strace (David Rodriguez)

I didn’t actually pay much attention to this session. From what I could gather, it was a great introduction to the strace command, and the presented case studies were quite useful. I use strace a lot at work, and I don’t recall noticing anything new during the session.

The reason my memory is so fuzzy is that, early in the session, I got the itch to clean up and post the strace-pstree script I wrote a while back. So I spent the hour doing that. Yes, I know it needs better documentation. It’s on my to-do list.

Sunday Keynote: Practical 3D Printing and the Open Source Community (Kyle Rankin)

Rather than stuff myself into the overcrowded and stuffy keynote room, I viewed it from the overflow room. While the environment was far more comfortable, the camera was only focused on the presenter, so I didn’t see any of the slides. I don’t know that it mattered much, but I did miss some of the jokes.

One of my fellow attendees took a pass on this keynote, stating that he didn’t want to listen to a bunch of mumbo jumbo about how cool 3D printing is and how it’s going to change the world. While I admit to not having paid too much attention to the talk (I foolishly had my laptop open), I don’t recall too much about changing the world. Most of what I caught was about the history of hobbyist 3D printing and what may be coming in the near future.

This keynote, in keeping with current events, also digressed into firearms. The printable AR-15 lower receiver was mentioned, along with its ability to only handle a few rounds of ammunition before failing. Based on reactions, it was difficult to judge the prevailing attitude among SCALE attendees. I’d say it was evenly split between anti- and pro-firearm people.

Your Baby Can Hack (Jenn Greenaway)

Actually, as was immediately pointed out, your baby can’t hack, and shouldn’t. It’s not healthy for babies to spend time in front of computer screens.

Of all the sessions I attended, this was my favorite. A lot of information was conveyed about the appropriate ages at which children can start using computers for different tasks. As anyone who has so much as spoken to me knows, since having children, I’ve developed a keen interest in evolutionary health and fitness. This session fit right in with all of that. My children are still young enough that I can immediately apply what I learned.

In perhaps the best demonstration ever that children are far smarter than we give them credit for, One Laptop Per Child ran an experiment, which resulted in Ethiopian children hacking Android. This should come as no real surprise to anyone who has watched their offspring learn to use an iPhone.

GTD with Emacs (Dennis Kibbe)

I’ve been using Vim, and prior to that, vi, for a cumulative 18 years. Between the muscle memory, my sizeable ~/.vimrc, and the Vim plugins I’ve written, I’ve never had any desire to learn emacs. That said, I’m always interested in seeing how people think and the things they’ve done to make their environment work for them.

This session did not disappoint. Dennis’s demonstration of org-mode was incredibly compelling. So much so that I immediately installed a mostly-compatible version for Vim. I’m not sure if I want to spend time playing with the Vim plugin or devote the time to learning enough about emacs to use org-mode. To track my time at work, I wrote some Vim macros and Perl scripts, but it could prove useful to determine how I can take advantage of org-mode to accomplish the task.

Hacking Your Health (David Uhlman)

As I wrote above, I’ve taken a keen interest in evolutionary health and fitness. As a geek, this session jumped right out at me. It didn’t disappoint. After a brief introduction to what the various measurements on a blood test mean, we were given a plethora of information on how to go about having tests run ourselves. The speaker has been involved in the health care industry, from various angles, for a number of years and spoke of the ins and outs of the system. He came off as quite knowledgeable and there was no shortage of questions from the audience. Now I know how to have a blood test run without the hassle of finding a doctor. Also cool: obtaining the raw data from a 3D body scan and using it to 3D print your own body parts.

The more amusing part of this session was the blood-alcohol guessing contest. Two volunteers were asked to have their BAC level tested, immediately consume an entire beer (beer is debatable: one drank a bottle of Corona, the other a bottle of Heineken), and finally test again after 45 minutes. The audience was to guess their final BACs, and a couple of lucky winners would receive health testing kits. One was an at-home blood type testing kit, the other was a hackable blood sugar tester. Apparently the latter is the only tester with Linux drivers available for it. For the curious, the final BAC for each volunteer was 0.00, though with the error margin for the testing device, it could have been as high as 0.02.

Honorary Mention: logstash – open source log processing and analytics (Jordan Sissel)

While I didn’t attend the logstash session, I find it worth mentioning, because seemingly everyone else did attend and afterwards it was all they could talk about.

logstash all the things

After attending the logstash session, people were ready to run their firstborn through it.

After hearing the excited and constant flow of ideas from my colleagues about what they could do with logstash, I can’t say I blame them. My day job uses Splunk, I’ve become quite familiar with using its API, and it’s unlikely to be replaced anytime soon, so I have no real interest in logstash at this time. However, I’ve made note of it, just in case I do find a need for it in the future.

The Fun & Games

Instead of making the not-so-fun drive from San Diego to LAX, I take Amtrak from Oceanside to Union Station and the bus from there to LAX. The Hilton is a quick shuttle ride (or walk) from there. Besides avoiding traffic, this gives me the opportunity to have a few drinks on my way to the conference. This year, my selection included a four pack of Oaked Arrogant Bastard.

Once everyone had arrived at the hotel on Friday, we walked to the Proud Bird, where I enjoyed a rare prime rib. The meal left me full well past lunch on Saturday. This actually helped me avoid the overpriced buffet at breakfast on Saturday morning.

For dinner on Saturday, we continued our now-four-year-old tradition1 of walking to Aliki’s Greek Taverna for dinner. I highly recommend the lahanodolmades, the pronunciation of which I usually stumble over. Being the only meal I’d consumed that day, I was left a bit hungry. When one of my friends, who did not join us for dinner, expressed a desire for fries at Carl’s Jr., I jumped at the chance for a burger.

If I’d known that food and beer would be available at game night, I may have opted for that instead. As it turns out, street-style tacos were being served. There was a beer line, but I never found out what was being served; I ended up in the hotel bar for a couple of pints instead (Sierra Nevada). Later, I did go back to game night. Once we kicked some people, playing Just Dance, off the Wii, a few of us played Mario Kart until the rented equipment was packed up.

After all was said and done2 on Sunday, we headed home, stopping at the Yard House in Irvine for dinner and drinks. After the beer over the weekend, I opted for two pints of Woodchuck Amber cider.

  1. The second year included a walk to the restaurant, but it was closed, because the cook had been involved in a car accident. []
  2. Actually, we left early, before the last session. []

EDC Kit

EDC stands for every day carry. An EDC kit is comprised of the various and sundry items one carries on their person every day.

My own EDC kit has grown and changed over the years. Recently I’ve wondered if it’s really worth taking the time to assemble so many items and to arrange them on my person. That question was answered for me last night.

I was training with a group of fellow martial artists in a tennis court. When training, I pack my kit in my bag, since my gi lacks pockets. This tennis court is equipped with a door that requires the use of a key both to enter and to exit. After the fellow in possession of the key went home, the door had closed behind him, leaving us trapped in the tennis court.

Looking around, I decided that I could probably scale the fence, even with my rather large and clumsy bag. However, I wasn’t convinced everyone could manage that. I called that plan B. Instead, I pulled out my flashlight to inspect the latch mechanism.

It's always a good idea to keep a flashlight anywhere you might need it.

It’s always a good idea to keep a flashlight anywhere you might need it.

On the inside of the door, the latch was accessible from underneath. Pulling out my multi-tool to amused cries of, “Hey look, it’s MacGyver!” I managed to reach in and manipulate the latch enough for the door to open.

No, it's not a Leatherman, but the Gerber is nice, too.

No, it’s not a Leatherman, but the Gerber is nice, too.

Never leave your EDC kit at home. I distinctly remember thinking to myself, “Should I bother packing this tonight?” With everyone carrying a mobile phone, we could have simply waited around for the fellow to return with the key. Still, I’m glad I packed my kit.

2013: An Introspection

I’ve been sitting on this post since new year’s eve. Well, that’s being generous. I’ve been sitting on a mostly empty draft since December 31. Last year, I reflected on my resolutions, but didn’t really come up with anything new for 2012. Since then, I’ve written all of six articles. In that time I’ve started seven articles, all of which languish in various states of incompletion. Will I ever post them? Maybe. There are seven others, older than one year, that languish along with them.

After sending our Christmas cards to family and friends, I took some heat for not including an annual letter. One of the reasons I started writing this article was to make up for that, but sitting on it for more than a week has been enlightening.

I am not a writer. I sometimes would like to be a writer, but I eventually have to come to terms with reality. I like the idea of being a writer, of people reading my prose, but I lack the dedication required to be one. Amusingly, I write for a living, but in the form of programming languages.

Over the course of the last month, I’ve considered shuttering this site entirely. I don’t post enough to make it worthwhile. I’m far more comfortable posting pithy comments on Twitter or sharing things on Google+. It is in these forums where my style of writing has consolidated. Blogs are the new website, focusing on a single topic. Online, public journals, which is what this site is, have been eclipsed by Facebook status updates.

In fact, this is the other reason I didn’t write a Christmas letter. Nothing of note happened over the last year. Even so, anyone who would have received a letter had already read about our lives, courtesy of Facebook.

Which is perhaps why I spent some time converting the website for my karate group from a static site into a blog. I still want to contribute to the greater good, as it were. This new site will provide a single topic, which will focus my efforts. Hopefully.

2012 MCRD Boot Camp Challenge

course_map02This weekend, for the second consecutive year and the third time overall, I ran in the Marine Corps Recruit Depot Boot Camp Challenge.  It’s a fun, but challenging, race that I look forward to. Sane people tend to avoid it, but I enjoy it. Both for the experience itself (it’s rare to be able to experience the same obstacle course as Marine recruits) and the bragging rights.

post_raceLast year I finished in 26:44. Going into this year’s race, I hoped to at least beat my time. Breaking 25 minutes would have been even better. My hopes were quickly dashed when the emcee announced that, because we the competitors had demanded a tougher challenge, twelve obstacles had been added to the race. Twelve! I’d call that a significant hit to a 5k time.

I felt good, but not great, during the first mile. Since I don’t much fancy running, I don’t do it very often. As such, I’m not a strong runner, and while I probably ran the first mile in around eight minutes, people were passing me. That first mile was fast, mainly because there was a distinct lack of hay bales this year. My training for this race is a combination of sprints, squats, and box jumps. I don’t care how strong a runner you are, scrambling over hay bales, leaping and crawling under logs, crawling through tunnels, and climbing over walls will tax your muscles to the point where running becomes quite difficult. In the back of my mind, I knew the missing hay bales was ominous, but I didn’t think much of it at the time. That is, until I reached the mid-point of the obstacle section.

I came up to a long line of people crawling in the sand. This wasn’t the kind of crawling babies do, but the kind of on-the-stomach crawling that Marines do. I was not at all ready for this added challenge and, as a result, my stamina was sapped by the end of the crawl. In fact, my shoulders are still sore as I write this, almost 36 hours later.

As I finished, I knew I was far from placing in the top three of my age division. Even so, I stuck around for a bit to enjoy the festivities and await the posting of the results. I ended up running into a friend from work, which was nice as this was the first time I ran the race without any compatriots (in 2004 I ran as part of a three man team, last year I ran with a friend). In any case, my final time was 31:53, which put me in 30th place in my division (a 17 place improvement over last year) and 372nd overall (a 32 place drop from last year). In retrospect, it’s difficult to compare my performance from one year to the next, as the obstacles are different. In particular, I’m sure I lost at least four minutes to the sand crawl.

Just in case the official race results vanish in the future, I’ve created a local copy, in which I’ve also highlighted my result.

souvenirIn addition to the traditional t-shirt given to each participant, last year I purchased a camouflage t-shirt for Kaylee. Unfortunately, there wasn’t anything for me to purchase this year. Of course, that doesn’t mean I didn’t leave without any souvenirs. Over to the right is a picture of one of them.

Seeing the Tour of California

We had a real treat today. We got to see the end of stage 6 of the Amgen Tour of California at Snow Summit. What’s interesting is that, not knowing about the race, we had originally intended to come up to Big Bear Lake on Friday night. At the last minute, we decided to drive up on Thursday night instead, which allowed us to take a stroll over to Summit Boulevard to see the race.

If I’d known about the race and the day’s events ahead of time, I may have brought my bike, to participate in the King of the Mountain Challenge:

The morning of the race, participants can ride on the same course as the professionals, just hours before the Pros make it to Big Bear. Start at the finish area at 10:00 a.m., ride to Snow Valley and then back through the finish line.

As a fan of the Tour de France, I’ve always wanted to see a race live. Watching a bicycle race live is not at all the same as watching a race on television, where you get to follow the riders for the length of the course. No, it’s all about the anticipation when viewing in person. The riders come up the road, pass you by, and are gone. Just like that.

I’ve included a copy of the spectator map from the Big Bear Climb and marked our location with a red dot. There were activities at the finish line that we didn’t partake of, and that’s where most of the crowd was. Only a few people were on the north side of Big Bear Boulevard, providing me an excellent view of the race.

The final stretch of stage six took the riders up Summit Boulevard, to the finish line at Snow Summit.

Very few people were on the north side of Big Bear Boulevard, leaving me ample space to observe the race and take pictures.

Perhaps a dozen or so escorts from the California Highway Patrol passed us, making sure the road was clear ahead of the riders.

Here comes the stage winner, Sylvain Georges of AG2R La Mondiale.

About a minute and a half later, the peloton rounded the last turn.

Bringing up the rear for this mountain finish is the polka dot jersey. According to the race web site, Sébastian Salas kept the jersey, so he must have fallen back near the end of the stage.

Automating On Call Jury Instructions

A version of this article is also published on my Perl blog.

Early in February, I received a jury summons for the United States District Court, Southern District of California. Prospective jurors for federal jury service (at least in this court) are placed on call for a period of about 30 days. I was to call for instructions on April 1 and potentially proceed to do so periodically until May 4 (assuming I wasn’t instructed to report).

Since my initial instruction date was nearly two months away, I created an entry for it in Google Calendar, and promptly forgot about it. On Monday, April 2, I was riding the train to work when I realized that I hadn’t remembered to check my instructions. Fortunately, after arriving at my office and checking my instructions, I had been deferred to the next day.

So I added a new entry in Google Calendar, this time with an SMS reminder. I proceeded to do this for most of April, checking my instructions and duplicating the calender entry with another SMS reminder.

I’m embarrassed to admit that it wasn’t until the last week of April that it occurred to me that I could automate the whole process. After all, isn’t automating drudgery the whole reason I ended up programming Perl in an engineering support group at my day job?

In addition to a telephone recording, jury instructions can be obtained online. In fact, this is the method I used all month. The form uses the HTTP POST method, so it wasn’t a simple matter of constructing an URL to fetch my instructions. While I could construct a POST request with curl(1) or the LWP module, it’s so much easier to do with with the WWW::Mechanize module.

my $mech = WWW::Mechanize->new();
$mech->get('http://jury.casd.uscourts.gov/AppearWeb/Default.aspx');
$mech->submit_form(
    form_name => 'Form1',
    fields    => {
        'ctl02$txtPart' => 'PARTICIPANT_ID',
        'ctl02$txtZip'  => 'ZIP_CODE',
    },
    button => 'ctl02$btnInstructions',
);

When I’m not supposed to report, the following message appears in the returned content:

<span id="ctl02_lblMsg">Please check again Sunday, April 29, after 6:00pm for further reporting instructions. Do NOT report at this time.</span>

Given how simple this is, I could parse it with a regular expression. But, I figured it was worth trying to do it right, so I searched CPAN and found the HTML::DOM module. I’ve worked a bit with DOM in JavaScript, so the module appealed to me. Annoyingly, the parse method only supports file names or file handles. Fortunately, this isn’t terribly difficult to work around and the whole thing isn’t much more verbose than using a regular expression.

my $dom = HTML::DOM->new;
$dom->parse_file( IO::Scalar->new( do { my $c = $mech->content; \$c } ) );
my $message = $dom->getElementById('ctl02_lblMsg')->innerHTML;

Now that I have the message what does it say? Thus far my instructions have always been to check again on another day, so I’ll need to work with what I know and defensively code for the exceptions.

if ( $message !~ /Do NOT report at this time/ ) {
    # We didn't see the message we wanted to see, so we'd better alert...
}

If I don’t see the known message, I send myself an alert (I happened to use the Email::Sender module in the script) and exit. If this happens, I’ll need to address it as it probably means I need to report (or I’m no longer on call).

However, if I do see the above message, I need to figure out when I’m supposed to check again. If this fails for some reason (e.g., I don’t know what the format looks like if the day is a single digit), I go through the alert process again. It’s rather important that this script be noisy, given the nature of what I’m doing and the limited knowledge I’m working with.

if ( $message !~ /Please check again (?<weekday>\w+), (?<month>\w+) (?<day>\d+)/ ) {
    # We couldn't parse the next date to check, so we'd better alert...
}
 
my $dt = DateTime::Format::DateParse->parse_datetime("$+{'weekday'}, $+{'day'} $+{'month'} 18:15");

I’ve hard-coded the time to check as 6:15 PM, because the instructions are always updated at 6:00 PM.

Finally, the script schedules itself to run again at the time indicated. Here I’ve broken out of Perl to use the at(1) command. Since I’m running the script on my Linode VPS, this seemed an easy way to accomplish the task of rescheduling.

open my $at, '|-', 'at', $dt->strftime('%R'), $dt->strftime('%F');
say {$at} "$0 2>/dev/null"; # $0 must be fully qualified or in PATH
close $at;

Running this script once will set the rescheduling process in motion, alleviating me of the need to run it again. If I’d thought of this at the beginning of April, I could have forgotten about the whole bother of checking for instructions several times per week. Oh well, live and learn.

I’ve posted the full script as a Gist on GitHub.

As a way of outsourcing the work and perhaps offer this type of service to a wider audience, I looked at ifttt and Yahoo! Pipes. Unfortunately, the former doesn’t appear to have a way to trigger on scraping an arbitrary web page, and the latter doesn’t appear to support the HTTP POST method. If anyone knows of an approach using existing services, I’m open to suggestions.

Updated on 30 April 2012.

Mojo::UserAgent

Posting this on blogs.perl.org resulted in a few comments (including a rant I completely agree with, but that’s beside the point). There was one suggestion that I try using Mojo::UserAgent instead of WWW::Mechanize.

My first attempt at doing so wasn’t particularly successful. After a while, I realized that I needed to manually do some of the work that WWW::Mechanize was doing for me. Namely, fetch the page, extract the hidden fields, and submit the form with these fields included (there’s a cookie involved, but it’s taken care of behind the scenes by both modules).

Because of this, the Mojo::UserAgent version is a bit more annoying to write, but I think this is more than made up for by the built-in access to the DOM.

my $ua  = Mojo::UserAgent->new;
my $url = 'http://jury.casd.uscourts.gov/AppearWeb/Default.aspx';
my $res = $ua->get($url)->res;  # initial fetch to get cookie and form fields
my $tx  = $ua->max_redirects(3)->post_form(
    $url => {
        '__VIEWSTATE'           => $res->dom('form#Form1 > input#__VIEWSTATE')->[0]->attrs('value'),
        '__EVENTVALIDATION'     => $res->dom('form#Form1 > input#__EVENTVALIDATION')->[0]->attrs('value'),
        'ctl02$txtPart'         => 'PARTICIPANT_ID',
        'ctl02$txtZip'          => 'ZIP_CODE',
        'ctl02$btnInstructions' => 'Reporting Instructions',
    }
);
 
$res = $tx->success or die $tx->error;
my $message = $res->dom('span#ctl02_lblMsg')->[0]->text;

WWW::Scripter

As I was working on the Mojo::UserAgent version of my script, I kept thinking how perfect it would be if WWW::Mechanize gave me access to the DOM in the same way. Well, as I was pushing the new jury-mojo.pl script to my Gist, cpansprout left a comment to not only tell me how I could remove my IO::Scalar hack, but that WWW::Scripter does exactly what I had just been wishing for. It’s like he read my mind.

my $mech = WWW::Scripter->new();
$mech->get('http://jury.casd.uscourts.gov/AppearWeb/Default.aspx');
$mech->submit_form(
    form_name => 'Form1',
    fields    => {
        'ctl02$txtPart' => 'PARTICIPANT_ID',
        'ctl02$txtZip'  => 'ZIP_CODE',
    },
    button => 'ctl02$btnInstructions',
);
 
my $message = $mech->document->getElementById('ctl02_lblMsg')->innerHTML;

I like this last version the most and have updated my Gist accordingly. Also, my automation worked and emailed me tonight to inform me that my jury service has concluded.

Broccoflower Curry Rice

As I noted in my last post, I had planned to try the broccoli and cauliflower combination again using a different method. Over the weekend, I picked up two broccoli florets and one head of cauliflower at the farmers market.

To prepare the broccoli and cauliflower, I chopped them into pieces small enough to fit into the hole in the top of my Cuisinart food processor. Replacing the blades with the shredding disk, I tediously pushed all of the vegetables through the spinning steel. This pretty well filled my 14 cup food processor, so keep that in mind when deciding how much to make. At first I thought I had made too much, and that the labor wasn’t worthwhile, but I’m thoroughly enjoying the leftovers.

I heated a few tablespoons of extra virgin olive oil in a 12 inch stainless steel frying pan, emptying the entire contents of the food processor bowl to it. To this, I added ample amounts of salt and curry powder. While stirring, I occasionally added more oil, since broccoli and cauliflower are pretty dry vegetables and will readily absorb it.

I need to get some white dishes, so I can take better pictures

It’s a pretty simple recipe and, while I was initially skeptical, it turned out downright amazing. The best part is, having given up rice and other grains, I finally have a staple I can use to soak up sauces.

If you try out this recipe, let me know in the comments what you used for flavor and how it turned out. Enjoy!

Coconut Curry Chicken with Broccoflower Couscous

For a couple of weeks, I’ve been posting my dinner creations to Facebook. I’ve been doing this for three reasons. First, a lot of people don’t know what they would cook when following a paleo lifestyle, so I want to share what I make after living this way for a couple of years. Second, I hope to inspire my friends and family with these meals. Finally, I like to show off.

The more mundane and repeated meals will probably remain as short posts on Facebook. However, I’d like to capture some of these dinners on my website. This will allow me to share with a wider audience as well as being a better archive of recipes.

Inspired by a post on Richard Nikoley’s website, I’d been thinking about trying Nacho Rubio’s curry chicken dish.

Instead of crafting my own curry powder (which I will do someday), I used curry powder from Trader Joe’s. I stirred about two tablespoons of it into about two tablespoons of extra virgin olive oil in my 12″ cast iron skillet. While the mixture was heating, I sliced one package of boneless and skinless chicken thighs into bite sized pieces, which I added to the skillet to cook. When the chicken was cooked through, I added 3/4 of a can of Trader Joe’s light coconut milk, turned up the heat, and let the moisture boil off until I was rewarded with a thick sauce.

While the chicken was cooking, I put two heads of broccoli and one head of cauliflower into the food processor to blend. For a while, it looked like I was making baby food. Once I got the broccoflower mixture into a 12″ stainless steel skillet with several tablespoons of Kerrygold butter and some salt, it started gaining a couscous-like texture.

Updated: I should point out that it was difficult to get the broccoli and cauliflower to process properly. I had overfilled the food processor’s bowl and without a liquid the larger pieces tended to bounce off the blades rather than being pulverized by them. Next time I prepare this, I will probably use the shredding blade (the one that mounts the blade at the top of the bowl) and plunge smaller pieces through it. If I do, I’ll be sure to report my results.

That was it, simple as that. I think it turned out pretty tasty.

After dinner, I treated myself to a cup of Turkish coffee, which I’m enjoying as I write these words. The coffee was Sumatra Blue Batak from Peet’s Coffee & Tea, to which I added turbinado sugar, cocoa powder, cinnamon, and nutmeg.

Repeated Capturing and Parsing in Perl

A version of this article is posted on my Perl blog.

When I checked my email after arriving at the office today, I found a query that had been sent to our internal Perl mail list. The questioner was trying to match a pattern repeatedly, capturing all of the results in an array. But, it wasn’t doing quite what he expected. The message, with minor edits, went a little something like the following.

I’m trying to extract key/value pairs from a file with the following contents:

- name = gcc_xo_src_clk, type = rcg
+ name = cxo_clk, type = xo, fgroup = xo, wt = 10, bloo = blah
? type = hm_mnd_rcg, name = bo : type = rcg_mn
+ name = pxo_clk

I was hoping to do something like this:

@list = $_ =~ m{ ^[-+?] \s* (\S+) \s* = \s* (\S+) \s* (?:, \s* (\S+) \s* = \s* (\S+) \s*)* }xms;

Thinking @list would be assigned the alternating key/value pairs. But the above doesn’t extract anything sane. Adding the /gc modifiers doesn’t make any difference.

If I do the following, it extracts the first two key/value pairs correctly (if the line has more than one pair).

@list = $_ =~ m{
    ^[-+?] \s* (\S+) \s* = \s* (\S+) \s*
    , \s* (\S+) \s* = \s* (\S+) \s*
}xms;

If I keep repeating the pattern in the second line, it keeps matching more key/value pairs.

I would expect using (?: )* should mean zero or more instances of match inside the parentheses, but obviously it’s not working. What am I doing wrong?

When I’m presented with a problem like this, that is some kind of structured data, I immediately think of writing a parser. I’ll get back to that in a bit, but I wanted to address the confusion about capturing in the pattern. And, in fact, that’s how the discussion on the mail list proceeded.

Repeated Capturing

First, let’s simplify the example to demonstrate why our seeker of wisdom isn’t getting back the list of items he expected.

my @matches = 'a b c d e' =~ /^(a) \s* (?: ([bcde]) \s* )*/xms;

say "(@matches)";   # prints "(a e)"

Capturing parentheses in Perl are treated somewhat like registers. Most Perl programmers are familiar with the $n variables, which hold the values of a successful pattern match. For example $1 holds the value matched by the first set of parentheses, $2 holds the value of the second set, and so on.

When a pattern is matched in list context, as above, it’s effectively the same as writing,

'a b c d e' =~ /^(a) \s* (?: ([bcde]) \s* )*/xms;

my @matches = ( $1, $2 );

These pattern match variables are scalars and, as such, will only hold a single value. That value is whatever the capturing parentheses matched last. So, in our simplified example, $1 matches a, which is obvious enough. As the pattern repeats, $2 would be set to b, then c, and so on until the final match of e.

That explains why the pattern match wasn’t returning the expected list. What can be done about it?

Capturing Along the Way

If we break down the sample data, we see that it generalizes to,

prefix key = value[, ...] [: key = value[, ...]]

The first approach that came to mind is to split the data into multiple lines. Each line can then have its initial prefix removed and saved, then parsed for its key/value pairs. That’s starting to look a lot like parsing, which I promised to get to later. For the purposes of this discussion, I wanted to be able to accomplish the task with a single regular expression.

To capture all of the values we want, we need to remove the repeating set of non-capturing parentheses. However, we still need to repeat the match, ideally returning all of the captured values in one statement. We can do that with the /g and /c regular expression modifiers.

my @list = $string =~ m{ ([-+?,:]) \s* (\w+) \s* = \s* (\w+) \s* }xmsgc;

I’ve done two things here. First, I replaced the \S character classes, used to match the key and value, with \w. The + pattern in a Perl regular expression is greedy, so the former character class was also matching the comma used to separate key/value pairs in the data. This left the literal comma with nothing to match, so was one source of confusion.

Second, I noted that the initial prefix, while syntactically important, could be viewed in the same way as the comma and colon separators. I combined all of these separators and added a capture around them so we can later make sense of the parsed data.

When matched against the data, the pattern results in a list like,

("-", "name", "gcc_xo_src_clk", ",", "type", "rcg", "+", "name", "cxo_clk", ...)

Now we can process the data using a simple state machine.

my $state = undef;

while ( my $token = shift @list ) {
    if ( $token eq '-' ) { $state = 'dash'; next; }
    # ...
    if ( $token eq ',' ) { next; }

    my $key   = shift @list;
    my $value = shift @list;

    if ( $state eq 'dash' ) {
        # ...
    }
}

Even though we did all of the data extraction using a single pattern match, it looks remarkably like … a parser! The pattern is simply the tokenizer used to feed tokens into our state machine, the parser.

Parsing

I stated at the outset that I looked at this as a parsing problem, so the solution I would use is most likely a parser. For simple, one-off scripts, I’d use a technique similar to the one I described in the previous section. However, for more complex data or a more complex script, I’d turn to a real parser.

In fact, one of my contributions to the thread that led me to compose this post included an example of using the $^R and $^N variables in embedded code blocks to demonstrate a rudimentary parser that allowed a simulated form of capturing within a repeated non-capturing group. I won’t go into any detail beyond showing what I wrote. As this was from an early point in the thread, the prefix is ignored in this example.

my @list = ();

my $kv = qr{
    (\w+) (?{ $^N; })           # capture the key
    \s* = \s* (\w+)
    (?{ $^R = [ $^R, $^N ]; })  # capture the value, saving the key
    (?{ push @list, @{ $^R } }) # push the key/value onto @list
}xms;

$data =~ m{ (?: ^[-+?] \s* $kv \s* (?:[,:] \s* $kv \s* )* )* }xms;

Fortunately for us, there are parsing modules on the CPAN.

Prior to Perl 5.10, Damian Conway had written Parse::RecDescent, but with the introduction of grammar-like facilities like named captures and named backreferences, Damian improved upon his original work and presented the Perl community with Regexp::Grammars.

What does a parser for this data built with Regexp::Grammars look like?

my $parser = qr{
    <[Line]>+

    <token: Prefix>   <MATCH= ([-+?]) >
    <token: Key>      <MATCH= (\w+) >
    <token: Value>    <MATCH= (\w+) >

    <rule: Line>      <Prefix> <Pairs> <Options>?
    <rule: Pairs>     <[Pair]>* % ,
    <rule: Pair>      <Key> = <Value>
    <rule: Options>   : <[Option]>* % ,
    <rule: Option>    <Key> = <Value>
}x;

if ( $data =~ $parser ) {
    # Do something with %/
}

This is a trivial example and all the work is left to be done by inspecting the parse tree in %/. However, the module supports embedded code that will be called when a token or rule matches, which can be used to process the data as its parsed.

References

Looking Ahead to 2012

One year ago in this space I attempted to start a new tradition for myself. While I rarely bothered in the past, mostly as an excuse to write a post, I jumped on the bandwagon and composed a set of resolutions for 2011. Now, in the waning hours of 2011, I wanted to take some time to review my resolutions and update them for 2012. Let’s take them from the top.

Spend more time with my daughter.

That should now read daughters, plural. In June we welcomed our second child, Brenna Rose, into the world. I’d like to think I’ve done well on this resolution. I spend every day looking forward to getting home to see my girls.

Read more.

I added this to the list because every year I would read a little less than the year before. I’ve managed to reverse this trend. Sure, I’ve added feeds to Google Reader, but I’ve removed a few as well. I’ve also opted to read actual books in my free time, reducing the amount of television I watch to a mere couple hours per week. I’ve read through two James Herriot books so far, with one remaining. I received a Barnes & Noble Nook for Christmas and purchased my first book for it on Thursday, The Ghosts of Belfast, which I’ve been rapidly devouring.

Write more.

While I frequently sat in front of my computer, pondering topics about which to write, I rarely found the necessary inspiration to put metaphorical pen to paper. Over the last 12 months, I composed a mere 16 posts. Four of those, a quarter of them, were about OSCON, which is far fewer than in years past when I would write an individual post for each session I attended. In addition, there are four drafts I never got around to completing. Looking them over, it appears that at least three of them are mostly done. I just need to give them a quick edit and post. Sadly, one of them is about Kaylee’s summer camp, so it’s a bit stale at this point.

Having read several blogs over the last year, I’ve developed a desire to be a more prolific writer. Not only personal posts, like this one, but anything that comes to mind. I can write about my programming work or even short fiction. I probably won’t delve into the realm of political commentary, but only because I lack any real desire to study the issues in enough depth to do them justice.

Be more Paleo.

More of the same here. I can count on one hand the number of bites of grains I had during the year. While my sweet tooth has been difficult to suppress, I really don’t eat very much sugar. One beer per week, to end Friday on a high note, is all I indulge in anymore. I managed to get my weight down to 158 pounds, which hasn’t budged in a few months. I would like to drop a few more pounds of body fat, so perhaps that is where I’ll focus my efforts for 2012.

Join a CrossFit Box.

I thought about it a few times, but never bothered. I have been going to the gym at work regularly and have been making decent strength gains. I’m mostly pleased with my progress on fitness and even earned my third degree black belt this year, so not accomplishing this particular resolution isn’t bothering me very much.

Get into MovNat.

The closest I got to this was our recent trip to Grape Day Park in Escondido. As a fitness program, it’s still something I want to do.

Actually use Facebook.

I added this one as a joke, but somehow I ended up using it. Sort of. I rarely post anything on Facebook, preferring Twitter and Google Plus, but I do try to keep tabs on what my friends are doing.

Looking Ahead to 2012

Aside from the above, what else should I look forward to doing in 2012?

I’ve recently been putting an emphasis on being more organized and getting things done in a more timely fashion. I’d like to keep this going into the new year, particularly with respect to the things that need doing around the house.

Segueing from organization into preparation, the recent power outage in San Diego made me take a serious look at our disaster preparations. My wife pokes fun at me for treating the entire situation as preparation for the zombie apocalypse, but I find it a fun way to stay motivated. Besides, when zombies show up and start eating people, who will be laughing then?

So that’s my theme for 2012: organization and preparation.